aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAfzal Mohammed <afzal@ti.com>2012-08-30 15:53:24 -0400
committerTony Lindgren <tony@atomide.com>2012-08-30 15:53:24 -0400
commit5c4684557b7e37afd42fa35f420f2f28bfb75442 (patch)
tree2e10f3cfe3a19f0d64b17f48f18eeeedeaeabbee
parent2ee30f0511758c1a21d3346bb88f25f7645ba108 (diff)
mtd: nand: omap2: use gpmc provided irqs
GPMC platform initialization provides it's clients with interrupts that can be used through struct resource. Make use of it for irq mode functionality. Also now write protect disable is done by GPMC, hence remove it. Signed-off-by: Afzal Mohammed <afzal@ti.com> Acked-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> [tony@atomide.com: updated to fix new warnings introduced] Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--drivers/mtd/nand/omap2.c78
1 files changed, 50 insertions, 28 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 3578c633e97e..27293e328517 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -137,7 +137,8 @@ struct omap_nand_info {
137 unsigned long mem_size; 137 unsigned long mem_size;
138 struct completion comp; 138 struct completion comp;
139 struct dma_chan *dma; 139 struct dma_chan *dma;
140 int gpmc_irq; 140 int gpmc_irq_fifo;
141 int gpmc_irq_count;
141 enum { 142 enum {
142 OMAP_NAND_IO_READ = 0, /* read */ 143 OMAP_NAND_IO_READ = 0, /* read */
143 OMAP_NAND_IO_WRITE, /* write */ 144 OMAP_NAND_IO_WRITE, /* write */
@@ -553,14 +554,12 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
553{ 554{
554 struct omap_nand_info *info = (struct omap_nand_info *) dev; 555 struct omap_nand_info *info = (struct omap_nand_info *) dev;
555 u32 bytes; 556 u32 bytes;
556 u32 irq_stat;
557 557
558 irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS);
559 bytes = readl(info->reg.gpmc_prefetch_status); 558 bytes = readl(info->reg.gpmc_prefetch_status);
560 bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes); 559 bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes);
561 bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */ 560 bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */
562 if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */ 561 if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */
563 if (irq_stat & 0x2) 562 if (this_irq == info->gpmc_irq_count)
564 goto done; 563 goto done;
565 564
566 if (info->buf_len && (info->buf_len < bytes)) 565 if (info->buf_len && (info->buf_len < bytes))
@@ -577,20 +576,17 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
577 (u32 *)info->buf, bytes >> 2); 576 (u32 *)info->buf, bytes >> 2);
578 info->buf = info->buf + bytes; 577 info->buf = info->buf + bytes;
579 578
580 if (irq_stat & 0x2) 579 if (this_irq == info->gpmc_irq_count)
581 goto done; 580 goto done;
582 } 581 }
583 gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat);
584 582
585 return IRQ_HANDLED; 583 return IRQ_HANDLED;
586 584
587done: 585done:
588 complete(&info->comp); 586 complete(&info->comp);
589 /* disable irq */
590 gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, 0);
591 587
592 /* clear status */ 588 disable_irq_nosync(info->gpmc_irq_fifo);
593 gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); 589 disable_irq_nosync(info->gpmc_irq_count);
594 590
595 return IRQ_HANDLED; 591 return IRQ_HANDLED;
596} 592}
@@ -624,9 +620,9 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)
624 goto out_copy; 620 goto out_copy;
625 621
626 info->buf_len = len; 622 info->buf_len = len;
627 /* enable irq */ 623
628 gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, 624 enable_irq(info->gpmc_irq_count);
629 (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT)); 625 enable_irq(info->gpmc_irq_fifo);
630 626
631 /* waiting for read to complete */ 627 /* waiting for read to complete */
632 wait_for_completion(&info->comp); 628 wait_for_completion(&info->comp);
@@ -674,12 +670,13 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
674 goto out_copy; 670 goto out_copy;
675 671
676 info->buf_len = len; 672 info->buf_len = len;
677 /* enable irq */ 673
678 gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, 674 enable_irq(info->gpmc_irq_count);
679 (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT)); 675 enable_irq(info->gpmc_irq_fifo);
680 676
681 /* waiting for write to complete */ 677 /* waiting for write to complete */
682 wait_for_completion(&info->comp); 678 wait_for_completion(&info->comp);
679
683 /* wait for data to flushed-out before reset the prefetch */ 680 /* wait for data to flushed-out before reset the prefetch */
684 tim = 0; 681 tim = 0;
685 limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); 682 limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
@@ -1300,9 +1297,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
1300 info->nand.options = pdata->devsize; 1297 info->nand.options = pdata->devsize;
1301 info->nand.options |= NAND_SKIP_BBTSCAN; 1298 info->nand.options |= NAND_SKIP_BBTSCAN;
1302 1299
1303 /* NAND write protect off */
1304 gpmc_cs_configure(info->gpmc_cs, GPMC_CONFIG_WP, 0);
1305
1306 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1300 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1307 if (res == NULL) { 1301 if (res == NULL) {
1308 err = -EINVAL; 1302 err = -EINVAL;
@@ -1392,17 +1386,39 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
1392 break; 1386 break;
1393 1387
1394 case NAND_OMAP_PREFETCH_IRQ: 1388 case NAND_OMAP_PREFETCH_IRQ:
1395 err = request_irq(pdata->gpmc_irq, 1389 info->gpmc_irq_fifo = platform_get_irq(pdev, 0);
1396 omap_nand_irq, IRQF_SHARED, "gpmc-nand", info); 1390 if (info->gpmc_irq_fifo <= 0) {
1391 dev_err(&pdev->dev, "error getting fifo irq\n");
1392 err = -ENODEV;
1393 goto out_release_mem_region;
1394 }
1395 err = request_irq(info->gpmc_irq_fifo, omap_nand_irq,
1396 IRQF_SHARED, "gpmc-nand-fifo", info);
1397 if (err) { 1397 if (err) {
1398 dev_err(&pdev->dev, "requesting irq(%d) error:%d", 1398 dev_err(&pdev->dev, "requesting irq(%d) error:%d",
1399 pdata->gpmc_irq, err); 1399 info->gpmc_irq_fifo, err);
1400 info->gpmc_irq_fifo = 0;
1401 goto out_release_mem_region;
1402 }
1403
1404 info->gpmc_irq_count = platform_get_irq(pdev, 1);
1405 if (info->gpmc_irq_count <= 0) {
1406 dev_err(&pdev->dev, "error getting count irq\n");
1407 err = -ENODEV;
1408 goto out_release_mem_region;
1409 }
1410 err = request_irq(info->gpmc_irq_count, omap_nand_irq,
1411 IRQF_SHARED, "gpmc-nand-count", info);
1412 if (err) {
1413 dev_err(&pdev->dev, "requesting irq(%d) error:%d",
1414 info->gpmc_irq_count, err);
1415 info->gpmc_irq_count = 0;
1400 goto out_release_mem_region; 1416 goto out_release_mem_region;
1401 } else {
1402 info->gpmc_irq = pdata->gpmc_irq;
1403 info->nand.read_buf = omap_read_buf_irq_pref;
1404 info->nand.write_buf = omap_write_buf_irq_pref;
1405 } 1417 }
1418
1419 info->nand.read_buf = omap_read_buf_irq_pref;
1420 info->nand.write_buf = omap_write_buf_irq_pref;
1421
1406 break; 1422 break;
1407 1423
1408 default: 1424 default:
@@ -1490,6 +1506,10 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
1490out_release_mem_region: 1506out_release_mem_region:
1491 if (info->dma) 1507 if (info->dma)
1492 dma_release_channel(info->dma); 1508 dma_release_channel(info->dma);
1509 if (info->gpmc_irq_count > 0)
1510 free_irq(info->gpmc_irq_count, info);
1511 if (info->gpmc_irq_fifo > 0)
1512 free_irq(info->gpmc_irq_fifo, info);
1493 release_mem_region(info->phys_base, info->mem_size); 1513 release_mem_region(info->phys_base, info->mem_size);
1494out_free_info: 1514out_free_info:
1495 kfree(info); 1515 kfree(info);
@@ -1508,8 +1528,10 @@ static int omap_nand_remove(struct platform_device *pdev)
1508 if (info->dma) 1528 if (info->dma)
1509 dma_release_channel(info->dma); 1529 dma_release_channel(info->dma);
1510 1530
1511 if (info->gpmc_irq) 1531 if (info->gpmc_irq_count > 0)
1512 free_irq(info->gpmc_irq, info); 1532 free_irq(info->gpmc_irq_count, info);
1533 if (info->gpmc_irq_fifo > 0)
1534 free_irq(info->gpmc_irq_fifo, info);
1513 1535
1514 /* Release NAND device, its internal structures and partitions */ 1536 /* Release NAND device, its internal structures and partitions */
1515 nand_release(&info->mtd); 1537 nand_release(&info->mtd);