From patchwork Wed Jul 9 10:26:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 4513171 Return-Path: X-Original-To: patchwork-linux-spi@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 9992DBEEAA for ; Wed, 9 Jul 2014 10:26:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AC031202F0 for ; Wed, 9 Jul 2014 10:26:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CB3EF202B4 for ; Wed, 9 Jul 2014 10:26:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755557AbaGIK0c (ORCPT ); Wed, 9 Jul 2014 06:26:32 -0400 Received: from andre.telenet-ops.be ([195.130.132.53]:38128 "EHLO andre.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755256AbaGIK0b (ORCPT ); Wed, 9 Jul 2014 06:26:31 -0400 Received: from ayla.of.borg ([84.193.72.141]) by andre.telenet-ops.be with bizsmtp id QASV1o00w32ts5g01ASVmz; Wed, 09 Jul 2014 12:26:30 +0200 Received: from geert by ayla.of.borg with local (Exim 4.76) (envelope-from ) id 1X4p53-0008AR-Ns; Wed, 09 Jul 2014 12:26:29 +0200 From: Geert Uytterhoeven To: Mark Brown Cc: Laurent Pinchart , linux-spi@vger.kernel.org, linux-sh@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH 1/2] [RFC] spi: rspi: Handle dmaengine_prep_slave_sg() failures gracefully Date: Wed, 9 Jul 2014 12:26:22 +0200 Message-Id: <1404901583-31366-1-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.7.9.5 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.6 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 As typically a shmobile SoC has less DMA channels than devices that can use DMA, we may want to prioritize access to the DMA channels in the future. This means that dmaengine_prep_slave_sg() may start failing arbitrarily. Handle dmaengine_prep_slave_sg() failures gracefully by falling back to PIO. Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart --- drivers/spi/spi-rspi.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 38fd938d6360..c850dfdfa9e3 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -477,7 +477,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, tx->sgl, tx->nents, DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc_tx) - return -EIO; + goto no_dma; irq_mask |= SPCR_SPTIE; } @@ -486,7 +486,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, rx->sgl, rx->nents, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc_rx) - return -EIO; + goto no_dma; irq_mask |= SPCR_SPRIE; } @@ -540,6 +540,12 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, enable_irq(rspi->rx_irq); return ret; + +no_dma: + pr_warn_once("%s %s: DMA not available, falling back to PIO\n", + dev_driver_string(&rspi->master->dev), + dev_name(&rspi->master->dev)); + return -EAGAIN; } static void rspi_receive_init(const struct rspi_data *rspi) @@ -593,8 +599,10 @@ static int rspi_common_transfer(struct rspi_data *rspi, if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { /* rx_buf can be NULL on RSPI on SH in TX-only Mode */ - return rspi_dma_transfer(rspi, &xfer->tx_sg, - xfer->rx_buf ? &xfer->rx_sg : NULL); + ret = rspi_dma_transfer(rspi, &xfer->tx_sg, + xfer->rx_buf ? &xfer->rx_sg : NULL); + if (ret != -EAGAIN) + return ret; } ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len); @@ -648,8 +656,11 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) { int ret; - if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) - return rspi_dma_transfer(rspi, &xfer->tx_sg, NULL); + if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { + ret = rspi_dma_transfer(rspi, &xfer->tx_sg, NULL); + if (ret != -EAGAIN) + return ret; + } ret = rspi_pio_transfer(rspi, xfer->tx_buf, NULL, xfer->len); if (ret < 0) @@ -663,8 +674,11 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) { - if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) - return rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); + if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { + int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); + if (ret != -EAGAIN) + return ret; + } return rspi_pio_transfer(rspi, NULL, xfer->rx_buf, xfer->len); }