From patchwork Wed Oct 8 04:38:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ray Jui X-Patchwork-Id: 5051331 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 60B029F295 for ; Wed, 8 Oct 2014 04:38:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8D141201F2 for ; Wed, 8 Oct 2014 04:38:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7A9682011B for ; Wed, 8 Oct 2014 04:38:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754692AbaJHEiL (ORCPT ); Wed, 8 Oct 2014 00:38:11 -0400 Received: from mail-gw3-out.broadcom.com ([216.31.210.64]:29304 "EHLO mail-gw3-out.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754547AbaJHEiK (ORCPT ); Wed, 8 Oct 2014 00:38:10 -0400 X-IronPort-AV: E=Sophos;i="5.04,674,1406617200"; d="scan'208";a="47521092" Received: from irvexchcas06.broadcom.com (HELO IRVEXCHCAS06.corp.ad.broadcom.com) ([10.9.208.53]) by mail-gw3-out.broadcom.com with ESMTP; 07 Oct 2014 21:40:44 -0700 Received: from IRVEXCHSMTP3.corp.ad.broadcom.com (10.9.207.53) by IRVEXCHCAS06.corp.ad.broadcom.com (10.9.208.53) with Microsoft SMTP Server (TLS) id 14.3.174.1; Tue, 7 Oct 2014 21:38:16 -0700 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP3.corp.ad.broadcom.com (10.9.207.53) with Microsoft SMTP Server id 14.3.174.1; Tue, 7 Oct 2014 21:38:16 -0700 Received: from mail.broadcom.com (lbrmn-lnxub44.ric.broadcom.com [10.136.8.49]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 57B7440FED; Tue, 7 Oct 2014 21:37:59 -0700 (PDT) From: Ray Jui To: Mark Brown CC: , , JD Zheng , Scott Branden , Ray Jui Subject: [PATCH] spi: pl022: Fix broken spidev when DMA is enabled Date: Tue, 7 Oct 2014 21:38:47 -0700 Message-ID: <1412743127-4523-1-git-send-email-rjui@broadcom.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_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 The PL022 SPI driver maps the DMA RX buffer before the DMA TX buffer. In most cases, the sequence of the mapping does not matter. But in cases where TX and RX happen to use the same buffer, e.g., spidev, it causes the cached TX data not written to memory, because the same memory has been marked invalid when dma_map_sg on the RX buffer is called The solution is to reverse the sequence so it maps the TX buffer before the RX buffer Signed-off-by: Ray Jui Reviewed-by: JD (Jiandong) Zheng Tested-by: Scott Branden Reviewed-by: Scott Branden --- drivers/spi/spi-pl022.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 1189cfd..edb7298 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -773,10 +773,10 @@ static void *next_transfer(struct pl022 *pl022) static void unmap_free_dma_scatter(struct pl022 *pl022) { /* Unmap and free the SG tables */ - dma_unmap_sg(pl022->dma_tx_channel->device->dev, pl022->sgt_tx.sgl, - pl022->sgt_tx.nents, DMA_TO_DEVICE); dma_unmap_sg(pl022->dma_rx_channel->device->dev, pl022->sgt_rx.sgl, pl022->sgt_rx.nents, DMA_FROM_DEVICE); + dma_unmap_sg(pl022->dma_tx_channel->device->dev, pl022->sgt_tx.sgl, + pl022->sgt_tx.nents, DMA_TO_DEVICE); sg_free_table(&pl022->sgt_rx); sg_free_table(&pl022->sgt_tx); } @@ -1026,16 +1026,16 @@ static int configure_dma(struct pl022 *pl022) pl022->cur_transfer->len, &pl022->sgt_tx); /* Map DMA buffers */ - rx_sglen = dma_map_sg(rxchan->device->dev, pl022->sgt_rx.sgl, - pl022->sgt_rx.nents, DMA_FROM_DEVICE); - if (!rx_sglen) - goto err_rx_sgmap; - tx_sglen = dma_map_sg(txchan->device->dev, pl022->sgt_tx.sgl, pl022->sgt_tx.nents, DMA_TO_DEVICE); if (!tx_sglen) goto err_tx_sgmap; + rx_sglen = dma_map_sg(rxchan->device->dev, pl022->sgt_rx.sgl, + pl022->sgt_rx.nents, DMA_FROM_DEVICE); + if (!rx_sglen) + goto err_rx_sgmap; + /* Send both scatterlists */ rxdesc = dmaengine_prep_slave_sg(rxchan, pl022->sgt_rx.sgl, @@ -1070,12 +1070,12 @@ err_txdesc: dmaengine_terminate_all(txchan); err_rxdesc: dmaengine_terminate_all(rxchan); + dma_unmap_sg(rxchan->device->dev, pl022->sgt_rx.sgl, + pl022->sgt_rx.nents, DMA_FROM_DEVICE); +err_rx_sgmap: dma_unmap_sg(txchan->device->dev, pl022->sgt_tx.sgl, pl022->sgt_tx.nents, DMA_TO_DEVICE); err_tx_sgmap: - dma_unmap_sg(rxchan->device->dev, pl022->sgt_rx.sgl, - pl022->sgt_tx.nents, DMA_FROM_DEVICE); -err_rx_sgmap: sg_free_table(&pl022->sgt_tx); err_alloc_tx_sg: sg_free_table(&pl022->sgt_rx);