From patchwork Tue Aug 21 09:44:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Afzal Mohammed X-Patchwork-Id: 1353531 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id F125FDFB34 for ; Tue, 21 Aug 2012 09:44:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755988Ab2HUJoY (ORCPT ); Tue, 21 Aug 2012 05:44:24 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:45929 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755883Ab2HUJoX (ORCPT ); Tue, 21 Aug 2012 05:44:23 -0400 Received: from dbdp20.itg.ti.com ([172.24.170.38]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id q7L9iHXC010188; Tue, 21 Aug 2012 04:44:18 -0500 Received: from DBDE71.ent.ti.com (localhost [127.0.0.1]) by dbdp20.itg.ti.com (8.13.8/8.13.8) with ESMTP id q7L9iHwW017519; Tue, 21 Aug 2012 15:14:17 +0530 (IST) Received: from dbdp32.itg.ti.com (172.24.170.251) by DBDE71.ent.ti.com (172.24.170.149) with Microsoft SMTP Server id 14.1.323.3; Tue, 21 Aug 2012 15:14:17 +0530 Received: from udx0156546.apr.dhcp.ti.com (dbdp20.itg.ti.com [172.24.170.38]) by dbdp32.itg.ti.com (8.13.8/8.13.8) with ESMTP id q7L9iG0a028264; Tue, 21 Aug 2012 15:14:16 +0530 From: Afzal Mohammed To: , , , CC: , Afzal Mohammed Subject: [PATCH v3 10/10] mtd: nand: omap2: use gpmc provided irqs Date: Tue, 21 Aug 2012 15:14:16 +0530 Message-ID: X-Mailer: git-send-email 1.7.1 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org 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 Acked-by: Artem Bityutskiy --- v3: Handle error path properly drivers/mtd/nand/omap2.c | 76 +++++++++++++++++++++++++++++----------------- 1 files changed, 48 insertions(+), 28 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index f65f7f8..0e9d7b3 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -137,7 +137,8 @@ struct omap_nand_info { unsigned long mem_size; struct completion comp; struct dma_chan *dma; - int gpmc_irq; + int gpmc_irq_fifo; + int gpmc_irq_count; enum { OMAP_NAND_IO_READ = 0, /* read */ OMAP_NAND_IO_WRITE, /* write */ @@ -553,14 +554,12 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev) { struct omap_nand_info *info = (struct omap_nand_info *) dev; u32 bytes; - u32 irq_stat; - irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); bytes = readl(info->reg.gpmc_prefetch_status); bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes); bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */ if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */ - if (irq_stat & 0x2) + if (this_irq == info->gpmc_irq_count) goto done; if (info->buf_len && (info->buf_len < bytes)) @@ -577,20 +576,17 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev) (u32 *)info->buf, bytes >> 2); info->buf = info->buf + bytes; - if (irq_stat & 0x2) + if (this_irq == info->gpmc_irq_count) goto done; } - gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); return IRQ_HANDLED; done: complete(&info->comp); - /* disable irq */ - gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, 0); - /* clear status */ - gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); + disable_irq_nosync(info->gpmc_irq_fifo); + disable_irq_nosync(info->gpmc_irq_count); return IRQ_HANDLED; } @@ -624,9 +620,9 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len) goto out_copy; info->buf_len = len; - /* enable irq */ - gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, - (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT)); + + enable_irq(info->gpmc_irq_count); + enable_irq(info->gpmc_irq_fifo); /* waiting for read to complete */ wait_for_completion(&info->comp); @@ -674,12 +670,13 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, goto out_copy; info->buf_len = len; - /* enable irq */ - gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, - (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT)); + + enable_irq(info->gpmc_irq_count); + enable_irq(info->gpmc_irq_fifo); /* waiting for write to complete */ wait_for_completion(&info->comp); + /* wait for data to flushed-out before reset the prefetch */ tim = 0; 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) info->nand.options = pdata->devsize; info->nand.options |= NAND_SKIP_BBTSCAN; - /* NAND write protect off */ - gpmc_cs_configure(info->gpmc_cs, GPMC_CONFIG_WP, 0); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { err = -EINVAL; @@ -1393,17 +1387,37 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) break; case NAND_OMAP_PREFETCH_IRQ: - err = request_irq(pdata->gpmc_irq, - omap_nand_irq, IRQF_SHARED, "gpmc-nand", info); + info->gpmc_irq_fifo = platform_get_irq(pdev, 0); + if (info->gpmc_irq_fifo <= 0) { + dev_err(&pdev->dev, "error getting fifo irq\n"); + goto out_release_mem_region; + } + err = request_irq(info->gpmc_irq_fifo, omap_nand_irq, + IRQF_SHARED, "gpmc-nand-fifo", info); if (err) { dev_err(&pdev->dev, "requesting irq(%d) error:%d", - pdata->gpmc_irq, err); + info->gpmc_irq_fifo, err); + info->gpmc_irq_fifo = 0; + goto out_release_mem_region; + } + + info->gpmc_irq_count = platform_get_irq(pdev, 1); + if (info->gpmc_irq_count <= 0) { + dev_err(&pdev->dev, "error getting count irq\n"); + goto out_release_mem_region; + } + err = request_irq(info->gpmc_irq_count, omap_nand_irq, + IRQF_SHARED, "gpmc-nand-count", info); + if (err) { + dev_err(&pdev->dev, "requesting irq(%d) error:%d", + info->gpmc_irq_count, err); + info->gpmc_irq_count = 0; goto out_release_mem_region; - } else { - info->gpmc_irq = pdata->gpmc_irq; - info->nand.read_buf = omap_read_buf_irq_pref; - info->nand.write_buf = omap_write_buf_irq_pref; } + + info->nand.read_buf = omap_read_buf_irq_pref; + info->nand.write_buf = omap_write_buf_irq_pref; + break; default: @@ -1491,6 +1505,10 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) out_release_mem_region: if (info->dma) dma_release_channel(info->dma); + if (info->gpmc_irq_count > 0) + free_irq(info->gpmc_irq_count, info); + if (info->gpmc_irq_fifo > 0) + free_irq(info->gpmc_irq_fifo, info); release_mem_region(info->phys_base, info->mem_size); out_free_info: kfree(info); @@ -1509,8 +1527,10 @@ static int omap_nand_remove(struct platform_device *pdev) if (info->dma) dma_release_channel(info->dma); - if (info->gpmc_irq) - free_irq(info->gpmc_irq, info); + if (info->gpmc_irq_count > 0) + free_irq(info->gpmc_irq_count, info); + if (info->gpmc_irq_fifo > 0) + free_irq(info->gpmc_irq_fifo, info); /* Release NAND device, its internal structures and partitions */ nand_release(&info->mtd);