From patchwork Sun Jan 12 10:27:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 3471011 Return-Path: X-Original-To: patchwork-linux-sh@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 035429F2E9 for ; Sun, 12 Jan 2014 10:28:08 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 14F4720149 for ; Sun, 12 Jan 2014 10:28:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2A59B20160 for ; Sun, 12 Jan 2014 10:28:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751137AbaALK17 (ORCPT ); Sun, 12 Jan 2014 05:27:59 -0500 Received: from gerard.telenet-ops.be ([195.130.132.48]:45090 "EHLO gerard.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751180AbaALK14 (ORCPT ); Sun, 12 Jan 2014 05:27:56 -0500 Received: from ayla.of.borg ([84.193.72.141]) by gerard.telenet-ops.be with bizsmtp id CyTs1n00b32ts5g0HyTsni; Sun, 12 Jan 2014 11:27:52 +0100 Received: from geert by ayla.of.borg with local (Exim 4.76) (envelope-from ) id 1W2IGm-0000QO-7B; 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 5/8] spi: rspi: Add support for no TX only mode Date: Sun, 12 Jan 2014 11:27:41 +0100 Message-Id: <1389522464-1569-6-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 RSPI variants lacking TX only mode, based on the SDK reference code. This is needed for RZ/A1H. The TX only mode flag is passed using platform data, defaulting to true for legacy RSPI. QSPI never has TX only mode. If TX only mode is not available, we have to wait for the receive interrupt bit to become set, and perform a dummy read, in the transmit path. Signed-off-by: Geert Uytterhoeven --- V2: - Spelling s/nevers/never/ drivers/spi/spi-rspi.c | 50 ++++++++++++++++++++++++++++++++++++++++------ include/linux/spi/rspi.h | 1 + 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index c3332d2b48e9..e507c2d6c710 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -200,6 +200,7 @@ struct rspi_data { unsigned dma_width_16bit:1; unsigned dma_callbacked:1; + unsigned txmode:1; }; static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset) @@ -259,6 +260,20 @@ struct spi_ops { /* * functions for RSPI */ +static void rspi_set_txmode(const struct rspi_data *rspi) +{ + if (rspi->txmode) + rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, + RSPI_SPCR); +} + +static void rspi_clear_txmode(const struct rspi_data *rspi) +{ + if (rspi->txmode) + rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, + RSPI_SPCR); +} + static int rspi_parse_platform_data(struct rspi_data *rspi, const struct rspi_plat_data *rspi_pd) { @@ -283,6 +298,11 @@ static int rspi_parse_platform_data(struct rspi_data *rspi, rspi->spdcr = 0; } + if (rspi_pd) + rspi->txmode = rspi_pd->txmode; + else + rspi->txmode = 1; /* legacy RSPI defaults to true */ + return 0; } @@ -329,6 +349,9 @@ static int qspi_parse_platform_data(struct rspi_data *rspi, rspi->data_width = 8; rspi->spdcr = 0; + /* No TX only mode */ + rspi->txmode = 0; + return 0; } @@ -422,8 +445,7 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, int remain = t->len; const u8 *data = t->tx_buf; while (remain > 0) { - rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, - RSPI_SPCR); + rspi_set_txmode(rspi); if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { dev_err(&rspi->master->dev, @@ -431,6 +453,15 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, return -ETIMEDOUT; } + if (!rspi->txmode && remain != t->len) { + if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, + SPCR_SPRIE) < 0) { + dev_err(&rspi->master->dev, + "%s: receive timeout\n", __func__); + return -ETIMEDOUT; + } + rspi_read_data(rspi); /* dummy read */ + } rspi_write_data(rspi, *data); data++; remain--; @@ -439,6 +470,14 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, /* Waiting for the last transmition */ rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE); + if (!rspi->txmode) { + if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { + dev_err(&rspi->master->dev, + "%s: receive timeout\n", __func__); + return -ETIMEDOUT; + } + rspi_read_data(rspi); /* dummy read */ + } return 0; } @@ -570,7 +609,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t) 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_set_txmode(rspi); rspi_enable_irq(rspi, SPCR_SPTIE); rspi->dma_callbacked = 0; @@ -621,8 +660,7 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, data = t->rx_buf; while (remain > 0) { - rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, - RSPI_SPCR); + rspi_clear_txmode(rspi); if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { dev_err(&rspi->master->dev, @@ -756,7 +794,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) 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_clear_txmode(rspi); rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); rspi->dma_callbacked = 0; diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h index 7316dd9c7ba9..0f5f612f0092 100644 --- a/include/linux/spi/rspi.h +++ b/include/linux/spi/rspi.h @@ -28,6 +28,7 @@ struct rspi_plat_data { unsigned int dma_rx_id; unsigned dma_width_16bit:1; /* DMAC read/write width = 16-bit */ + unsigned txmode:1; /* TX only mode */ u16 num_chipselect; };