From patchwork Wed May 20 18:06:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 6448311 X-Patchwork-Delegate: geert@linux-m68k.org 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B0F559F1CC for ; Wed, 20 May 2015 18:06:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D0A092034F for ; Wed, 20 May 2015 18:06:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 945C220382 for ; Wed, 20 May 2015 18:06:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754054AbbETSGV (ORCPT ); Wed, 20 May 2015 14:06:21 -0400 Received: from xavier.telenet-ops.be ([195.130.132.52]:48274 "EHLO xavier.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753419AbbETSGT (ORCPT ); Wed, 20 May 2015 14:06:19 -0400 Received: from ayla.of.borg ([84.193.93.87]) by xavier.telenet-ops.be with bizsmtp id WJ6G1q00j1t5w8s01J6GCp; Wed, 20 May 2015 20:06:17 +0200 Received: from ramsan.of.borg ([192.168.97.29] helo=ramsan) by ayla.of.borg with esmtp (Exim 4.82) (envelope-from ) id 1Yv8Nk-0006Uc-Kx; Wed, 20 May 2015 20:06:16 +0200 Received: from geert by ramsan with local (Exim 4.82) (envelope-from ) id 1Yv8Np-00030p-0L; Wed, 20 May 2015 20:06:21 +0200 From: Geert Uytterhoeven To: Magnus Damm , Laurent Pinchart , Nobuhiro Iwamatsu , Yoshihiro Kaneko , Wolfram Sang , Guennadi Liakhovetski Cc: linux-sh@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH 1/8] serial: sh-sci: Use correct device for DMA mapping with IOMMU Date: Wed, 20 May 2015 20:06:07 +0200 Message-Id: <1432145174-11534-2-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1432145174-11534-1-git-send-email-geert+renesas@glider.be> References: <1432145174-11534-1-git-send-email-geert+renesas@glider.be> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@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=ham 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 To function correctly in the presence of an IOMMU, the DMA buffers must be managed using the DMA channel's device instead of the platform device's device. Make sure to free the DMA memory before releasing the channel, and avoid freeing it twice (when DMA initialization succeeded before, but failed partially on next open). Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart --- drivers/tty/serial/sh-sci.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 583aa563d4038f8b..8756d186e86891ac 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1372,10 +1372,13 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio) s->chan_rx = NULL; s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL; + if (sg_dma_address(&s->sg_rx[0])) { + dma_free_coherent(chan->device->dev, s->buf_len_rx * 2, + sg_virt(&s->sg_rx[0]), + sg_dma_address(&s->sg_rx[0])); + sg_dma_address(&s->sg_rx[0]) = 0; + } dma_release_channel(chan); - if (sg_dma_address(&s->sg_rx[0])) - dma_free_coherent(port->dev, s->buf_len_rx * 2, - sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); if (enable_pio) sci_start_rx(port); } @@ -1706,7 +1709,8 @@ static void sci_request_dma(struct uart_port *port) sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), UART_XMIT_SIZE, (uintptr_t)port->state->xmit.buf & ~PAGE_MASK); - nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); + nent = dma_map_sg(chan->device->dev, &s->sg_tx, 1, + DMA_TO_DEVICE); if (!nent) sci_tx_dma_release(s, false); else @@ -1735,8 +1739,9 @@ static void sci_request_dma(struct uart_port *port) s->chan_rx = chan; s->buf_len_rx = 2 * max(16, (int)port->fifosize); - buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2, - &dma[0], GFP_KERNEL); + buf[0] = dma_alloc_coherent(chan->device->dev, + s->buf_len_rx * 2, &dma[0], + GFP_KERNEL); if (!buf[0]) { dev_warn(port->dev,