lkml.org 
[lkml]   [2015]   [Sep]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 09/27] mtd: nand: omap2: manage NAND interrupts
    Date
    Manage NAND interrupts here using the GPMC IRQ ops.

    This causes performance in prefetch-irq mode to be increased

    from
    [ 38.252811] mtd_speedtest: eraseblock write speed is 5576 KiB/s
    [ 39.265259] mtd_speedtest: eraseblock read speed is 8192 KiB/s

    to
    [ 35.666446] mtd_speedtest: eraseblock write speed is 6537 KiB/s
    [ 36.444842] mtd_speedtest: eraseblock read speed is 10680 KiB/s

    Test results on dra7-evm using mtd_speedtest.ko

    Signed-off-by: Roger Quadros <rogerq@ti.com>
    ---
    drivers/mtd/nand/omap2.c | 65 +++++++++++++++++++++++-------------------------
    1 file changed, 31 insertions(+), 34 deletions(-)

    diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
    index 0eb0b8c..267bcdd 100644
    --- a/drivers/mtd/nand/omap2.c
    +++ b/drivers/mtd/nand/omap2.c
    @@ -162,8 +162,7 @@ struct omap_nand_info {
    enum omap_ecc ecc_opt;
    struct completion comp;
    struct dma_chan *dma;
    - int gpmc_irq_fifo;
    - int gpmc_irq_count;
    + int gpmc_irq;
    enum {
    OMAP_NAND_IO_READ = 0, /* read */
    OMAP_NAND_IO_WRITE, /* write */
    @@ -579,12 +578,17 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
    {
    struct omap_nand_info *info = (struct omap_nand_info *) dev;
    u32 bytes;
    + u32 irqstatus;
    +
    + irqstatus = info->ops->nand_irq_status();
    + if (!irqstatus)
    + return IRQ_NONE;

    bytes = readl(info->reg.gpmc_prefetch_status);
    bytes = 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 (this_irq == info->gpmc_irq_count)
    + if (irqstatus & GPMC_IRQENABLE_TERMCOUNT)
    goto done;

    if (info->buf_len && (info->buf_len < bytes))
    @@ -601,17 +605,25 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev)
    (u32 *)info->buf, bytes >> 2);
    info->buf = info->buf + bytes;

    - if (this_irq == info->gpmc_irq_count)
    + if (irqstatus & GPMC_IRQENABLE_TERMCOUNT)
    goto done;
    }

    + /* Clear FIFOEVENT STATUS */
    + info->ops->nand_irq_clear(GPMC_NAND_IRQ_FIFOEVENT);
    +
    return IRQ_HANDLED;

    done:
    complete(&info->comp);

    - disable_irq_nosync(info->gpmc_irq_fifo);
    - disable_irq_nosync(info->gpmc_irq_count);
    + /* Clear FIFOEVENT and TERMCOUNT STATUS */
    + info->ops->nand_irq_clear(GPMC_NAND_IRQ_FIFOEVENT);
    + info->ops->nand_irq_clear(GPMC_NAND_IRQ_TERMCOUNT);
    +
    + /* Disable Interrupt generation */
    + info->ops->nand_irq_disable(GPMC_NAND_IRQ_FIFOEVENT);
    + info->ops->nand_irq_disable(GPMC_NAND_IRQ_TERMCOUNT);

    return IRQ_HANDLED;
    }
    @@ -646,8 +658,9 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)

    info->buf_len = len;

    - enable_irq(info->gpmc_irq_count);
    - enable_irq(info->gpmc_irq_fifo);
    + /* Enable Interrupt generation */
    + info->ops->nand_irq_enable(GPMC_NAND_IRQ_TERMCOUNT);
    + info->ops->nand_irq_enable(GPMC_NAND_IRQ_FIFOEVENT);

    /* waiting for read to complete */
    wait_for_completion(&info->comp);
    @@ -696,8 +709,9 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,

    info->buf_len = len;

    - enable_irq(info->gpmc_irq_count);
    - enable_irq(info->gpmc_irq_fifo);
    + /* Enable Interrupt generation */
    + info->ops->nand_irq_enable(GPMC_NAND_IRQ_TERMCOUNT);
    + info->ops->nand_irq_enable(GPMC_NAND_IRQ_FIFOEVENT);

    /* waiting for write to complete */
    wait_for_completion(&info->comp);
    @@ -1776,35 +1790,18 @@ static int omap_nand_probe(struct platform_device *pdev)
    break;

    case NAND_OMAP_PREFETCH_IRQ:
    - info->gpmc_irq_fifo = platform_get_irq(pdev, 0);
    - if (info->gpmc_irq_fifo <= 0) {
    - dev_err(&pdev->dev, "error getting fifo irq\n");
    - err = -ENODEV;
    - goto return_error;
    - }
    - err = devm_request_irq(&pdev->dev, info->gpmc_irq_fifo,
    - omap_nand_irq, IRQF_SHARED,
    - "gpmc-nand-fifo", info);
    - if (err) {
    - dev_err(&pdev->dev, "requesting irq(%d) error:%d",
    - info->gpmc_irq_fifo, err);
    - info->gpmc_irq_fifo = 0;
    - goto return_error;
    - }
    -
    - info->gpmc_irq_count = platform_get_irq(pdev, 1);
    - if (info->gpmc_irq_count <= 0) {
    - dev_err(&pdev->dev, "error getting count irq\n");
    + info->gpmc_irq = platform_get_irq(pdev, 0);
    + if (info->gpmc_irq <= 0) {
    + dev_err(&pdev->dev, "error getting GPMC irq\n");
    err = -ENODEV;
    goto return_error;
    }
    - err = devm_request_irq(&pdev->dev, info->gpmc_irq_count,
    - omap_nand_irq, IRQF_SHARED,
    - "gpmc-nand-count", info);
    + err = devm_request_irq(&pdev->dev, info->gpmc_irq,
    + omap_nand_irq, IRQF_SHARED,
    + DRIVER_NAME, info);
    if (err) {
    dev_err(&pdev->dev, "requesting irq(%d) error:%d",
    - info->gpmc_irq_count, err);
    - info->gpmc_irq_count = 0;
    + info->gpmc_irq, err);
    goto return_error;
    }

    --
    2.1.4


    \
     
     \ /
      Last update: 2015-09-18 17:21    [W:4.191 / U:0.288 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site