From patchwork Tue Dec 24 11:40:43 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 3401911 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7A9679F314 for ; Tue, 24 Dec 2013 11:41:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 83F3E205F5 for ; Tue, 24 Dec 2013 11:41:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 41974205B5 for ; Tue, 24 Dec 2013 11:41:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752132Ab3LXLlZ (ORCPT ); Tue, 24 Dec 2013 06:41:25 -0500 Received: from juliette.telenet-ops.be ([195.130.137.74]:39549 "EHLO juliette.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751974Ab3LXLlY (ORCPT ); Tue, 24 Dec 2013 06:41:24 -0500 Received: from ayla.of.borg ([84.193.72.141]) by juliette.telenet-ops.be with bizsmtp id 5PhM1n03c32ts5g06PhMo4; Tue, 24 Dec 2013 12:41:21 +0100 Received: from geert by ayla.of.borg with local (Exim 4.76) (envelope-from ) id 1VvQMT-0000qg-Nl; Tue, 24 Dec 2013 12:41:21 +0100 From: Geert Uytterhoeven To: linux-spi@vger.kernel.org Cc: linux-sh@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH 3/8] spi: rspi: Add support for more than one interrupt Date: Tue, 24 Dec 2013 12:40:43 +0100 Message-Id: <1387885248-28425-4-git-send-email-geert+renesas@linux-m68k.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1387885248-28425-1-git-send-email-geert+renesas@linux-m68k.org> References: <1387885248-28425-1-git-send-email-geert+renesas@linux-m68k.org> Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-7.4 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 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 --- drivers/spi/spi-rspi.c | 57 +++++++++++++++++++++++++++++----------------- include/linux/spi/rspi.h | 2 +- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 46232e3b6e8c..c7bbc54ef785 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. @@ -167,6 +167,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; @@ -178,12 +179,13 @@ struct rspi_data { spinlock_t lock; struct clk *clk; u8 spsr; + int irq[MAX_NUM_IRQ]; + unsigned int numirq; 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; @@ -462,7 +464,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t) const void *buf = NULL; struct dma_async_tx_descriptor *desc; unsigned len; - int ret = 0; + int i, ret = 0; if (rspi->dma_width_16bit) { void *tmp; @@ -499,7 +501,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->numirq; i++) + disable_irq(rspi->irq[i]); rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR); rspi_enable_irq(rspi, SPCR_SPTIE); @@ -518,7 +521,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->numirq; i++) + enable_irq(rspi->irq[i]); end: rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE); @@ -628,7 +632,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) void *dummy = NULL, *rx_buf = NULL; struct dma_async_tx_descriptor *desc, *desc_dummy; unsigned len; - int ret = 0; + int i, ret = 0; if (rspi->dma_width_16bit) { /* @@ -685,7 +689,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->numirq; i++) + disable_irq(rspi->irq[i]); rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR); rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); @@ -708,7 +713,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->numirq; i++) + enable_irq(rspi->irq[i]); end: rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE); @@ -918,7 +924,7 @@ static int rspi_probe(struct platform_device *pdev) struct resource *res; struct spi_master *master; struct rspi_data *rspi; - int ret, irq; + int i, ret, irq; char clk_name[16]; const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev); const struct spi_ops *ops; @@ -931,12 +937,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"); @@ -948,6 +948,19 @@ static int rspi_probe(struct platform_device *pdev) rspi->ops = ops; rspi->master = master; + for (i = 0; i < MAX_NUM_IRQ; i++) { + irq = platform_get_irq(pdev, i); + if (irq < 0) { + if (rspi->numirq) + break; + dev_err(&pdev->dev, "platform_get_irq error\n"); + ret = -ENODEV; + goto error1; + } + rspi->irq[i] = irq; + rspi->numirq++; + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rspi->addr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(rspi->addr)) { @@ -979,14 +992,16 @@ 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 < rspi->numirq; i++) { + ret = devm_request_irq(&pdev->dev, rspi->irq[i], rspi_irq, 0, + dev_name(&pdev->dev), rspi); + if (ret < 0) { + dev_err(&pdev->dev, "request_irq %d error\n", + rspi->irq[i]); + goto error1; + } } - rspi->irq = irq; ret = rspi_request_dma(rspi, pdev); if (ret < 0) { dev_err(&pdev->dev, "rspi_request_dma failed.\n"); diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h index a25bd6f65e7f..3f55232f74ff 100644 --- a/include/linux/spi/rspi.h +++ b/include/linux/spi/rspi.h @@ -1,7 +1,7 @@ /* * Renesas SPI driver * - * Copyright (C) 2012 Renesas Solutions Corp. + * Copyright (C) 2012, 2013 Renesas Solutions Corp. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by