From patchwork Thu Jul 16 18:21:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 6810351 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 9B04F9F380 for ; Thu, 16 Jul 2015 18:22:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B675C20680 for ; Thu, 16 Jul 2015 18:22:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C14F220684 for ; Thu, 16 Jul 2015 18:22:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756212AbbGPSWX (ORCPT ); Thu, 16 Jul 2015 14:22:23 -0400 Received: from laurent.telenet-ops.be ([195.130.137.89]:37835 "EHLO laurent.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756198AbbGPSWE (ORCPT ); Thu, 16 Jul 2015 14:22:04 -0400 Received: from ayla.of.borg ([84.193.93.87]) by laurent.telenet-ops.be with bizsmtp id t6N21q00W1t5w8s016N2XQ; Thu, 16 Jul 2015 20:22:02 +0200 Received: from ramsan.of.borg ([192.168.97.29] helo=ramsan) by ayla.of.borg with esmtp (Exim 4.82) (envelope-from ) id 1ZFnnF-000083-Ns; Thu, 16 Jul 2015 20:22:02 +0200 Received: from geert by ramsan with local (Exim 4.82) (envelope-from ) id 1ZFnnG-0007KG-Rk; Thu, 16 Jul 2015 20:22:02 +0200 From: Geert Uytterhoeven To: Magnus Damm , Laurent Pinchart , Nobuhiro Iwamatsu , Yoshihiro Kaneko , Kazuya Mizuguchi , Koji Matsuoka , Wolfram Sang , Guennadi Liakhovetski Cc: linux-sh@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH/RFC v2 04/29] serial: sh-sci: Use correct device for DMA mapping with IOMMU Date: Thu, 16 Jul 2015 20:21:35 +0200 Message-Id: <1437070920-28069-5-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1437070920-28069-1-git-send-email-geert+renesas@glider.be> References: <1437070920-28069-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=-8.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 --- v2: - Add Acked-by. --- 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 dc8d1b6a82684c17..6431b1fb9c162e77 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,