From patchwork Sun Jan 12 10:27:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 3471131 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 08859C02DC for ; Sun, 12 Jan 2014 10:28:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1C0DB2013A for ; Sun, 12 Jan 2014 10:28:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EE7E620103 for ; Sun, 12 Jan 2014 10:28:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751248AbaALK2Q (ORCPT ); Sun, 12 Jan 2014 05:28:16 -0500 Received: from jacques.telenet-ops.be ([195.130.132.50]:39461 "EHLO jacques.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751198AbaALK2M (ORCPT ); Sun, 12 Jan 2014 05:28:12 -0500 Received: from ayla.of.borg ([84.193.72.141]) by jacques.telenet-ops.be with bizsmtp id CyTs1n00Z32ts5g0JyTsRl; Sun, 12 Jan 2014 11:27:53 +0100 Received: from geert by ayla.of.borg with local (Exim 4.76) (envelope-from ) id 1W2IGm-0000QG-0x; Sun, 12 Jan 2014 11:27:52 +0100 From: Geert Uytterhoeven To: Mark Brown Cc: linux-spi@vger.kernel.org, linux-sh@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH V2 3/8] spi: rspi: Add support for more than one interrupt Date: Sun, 12 Jan 2014 11:27:39 +0100 Message-Id: <1389522464-1569-4-git-send-email-geert@linux-m68k.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1389522464-1569-1-git-send-email-geert@linux-m68k.org> References: <1389522464-1569-1-git-send-email-geert@linux-m68k.org> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Geert Uytterhoeven Add support for up to 3 interrupts, based on the SDK reference code. This is needed for RZ/A1H. Minimum 1 and maximum 3 interrupts can be passed via platform device resources. Signed-off-by: Geert Uytterhoeven --- v2: - s/irq[]/irqs[]/ - s/numirq/num_irqs/ - Use unsigned int for loop counters that cannot be negative - Merge the platform_get_irq() and devm_request_irq() loops - Do not update copyright header in further untouched rspi.h drivers/spi/spi-rspi.c | 52 +++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index eded530763ca..45da760281f9 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -1,7 +1,7 @@ /* * SH RSPI driver * - * Copyright (C) 2012 Renesas Solutions Corp. + * Copyright (C) 2012, 2013 Renesas Solutions Corp. * * Based on spi-sh.c: * Copyright (C) 2011 Renesas Solutions Corp. @@ -176,6 +176,7 @@ #define SPBFCR_RXTRG_MASK 0x07 /* Receive Buffer Data Triggering Number */ #define DUMMY_DATA 0x00 +#define MAX_NUM_IRQ 3 struct rspi_data { void __iomem *addr; @@ -187,12 +188,13 @@ struct rspi_data { spinlock_t lock; struct clk *clk; u8 spsr; + int irqs[MAX_NUM_IRQ]; + unsigned int num_irqs; const struct spi_ops *ops; /* for dmaengine */ struct dma_chan *chan_tx; struct dma_chan *chan_rx; - int irq; unsigned dma_width_16bit:1; unsigned dma_callbacked:1; @@ -470,7 +472,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t) struct scatterlist sg; const void *buf = NULL; struct dma_async_tx_descriptor *desc; - unsigned len; + unsigned int len, i; int ret = 0; if (rspi->dma_width_16bit) { @@ -508,7 +510,8 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t) * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be * called. So, this driver disables the IRQ while DMA transfer. */ - disable_irq(rspi->irq); + for (i = 0; i < rspi->num_irqs; i++) + disable_irq(rspi->irqs[i]); rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR); rspi_enable_irq(rspi, SPCR_SPTIE); @@ -527,7 +530,8 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t) ret = -ETIMEDOUT; rspi_disable_irq(rspi, SPCR_SPTIE); - enable_irq(rspi->irq); + for (i = 0; i < rspi->num_irqs; i++) + enable_irq(rspi->irqs[i]); end: rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE); @@ -636,7 +640,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) struct scatterlist sg, sg_dummy; void *dummy = NULL, *rx_buf = NULL; struct dma_async_tx_descriptor *desc, *desc_dummy; - unsigned len; + unsigned int len, i; int ret = 0; if (rspi->dma_width_16bit) { @@ -694,7 +698,8 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be * called. So, this driver disables the IRQ while DMA transfer. */ - disable_irq(rspi->irq); + for (i = 0; i < rspi->num_irqs; i++) + disable_irq(rspi->irqs[i]); rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR); rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); @@ -717,7 +722,8 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) ret = -ETIMEDOUT; rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); - enable_irq(rspi->irq); + for (i = 0; i < rspi->num_irqs; i++) + enable_irq(rspi->irqs[i]); end: rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE); @@ -928,6 +934,7 @@ static int rspi_probe(struct platform_device *pdev) struct spi_master *master; struct rspi_data *rspi; int ret, irq; + unsigned int i; char clk_name[16]; const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev); const struct spi_ops *ops; @@ -940,12 +947,6 @@ static int rspi_probe(struct platform_device *pdev) return -ENODEV; } - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "platform_get_irq error\n"); - return -ENODEV; - } - master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data)); if (master == NULL) { dev_err(&pdev->dev, "spi_alloc_master error.\n"); @@ -988,14 +989,25 @@ static int rspi_probe(struct platform_device *pdev) master->transfer = rspi_transfer; master->cleanup = rspi_cleanup; - ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0, - dev_name(&pdev->dev), rspi); - if (ret < 0) { - dev_err(&pdev->dev, "request_irq error\n"); - goto error1; + for (i = 0; i < MAX_NUM_IRQ; i++) { + irq = platform_get_irq(pdev, i); + if (irq < 0) { + if (rspi->num_irqs) + break; + dev_err(&pdev->dev, "platform_get_irq error\n"); + ret = -ENODEV; + goto error1; + } + ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0, + dev_name(&pdev->dev), rspi); + if (ret < 0) { + dev_err(&pdev->dev, "request_irq %d error\n", irq); + goto error1; + } + rspi->irqs[i] = irq; + rspi->num_irqs++; } - rspi->irq = irq; ret = rspi_request_dma(rspi, pdev); if (ret < 0) { dev_err(&pdev->dev, "rspi_request_dma failed.\n");