From patchwork Mon Jan 9 16:06:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Bailon X-Patchwork-Id: 90517 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp152207qgi; Mon, 9 Jan 2017 08:08:32 -0800 (PST) X-Received: by 10.98.149.93 with SMTP id p90mr8707289pfd.72.1483978111940; Mon, 09 Jan 2017 08:08:31 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f1si89217578plf.93.2017.01.09.08.08.31; Mon, 09 Jan 2017 08:08:31 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-usb-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@baylibre-com.20150623.gappssmtp.com; spf=pass (google.com: best guess record for domain of linux-usb-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-usb-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S970234AbdAIQIX (ORCPT + 4 others); Mon, 9 Jan 2017 11:08:23 -0500 Received: from mail-wm0-f46.google.com ([74.125.82.46]:36331 "EHLO mail-wm0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S970258AbdAIQH2 (ORCPT ); Mon, 9 Jan 2017 11:07:28 -0500 Received: by mail-wm0-f46.google.com with SMTP id c85so102517192wmi.1 for ; Mon, 09 Jan 2017 08:07:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oskJhSPCSkNSHLmbFjxKzvB8Bj54KC5P7VskqLpjP9U=; b=S0Rg4icmETipsIGb33aLP5GLDF1kq0/KeezdFT6sCN2TYBfcHUXsF2OZyFT1a1pLrB TNP/sKznNGCV7WphnKF9uyYFgky49YETW7W2emjhTqPI5IK1AdDC2Fym2TwSiSLBJupI CmjN1RvMtxmHSmAncWQBPTZzKYoUvXdZcP/MtqtrGuQXjq1Gy5dWj0g9sKehgnJVcAjY 0IG0KrAysfYik8UtN/nm1P+/Zw/d1t+7yUfHr4KcxQsOHNpgEKpK8bDtE6MVjJquliNb IVPddltdmGyTZsNMPgtwD/y19vQMIxyNPqrocVmFN6NvUjUVTjkRbasERP/pufexP79M 7Z9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=oskJhSPCSkNSHLmbFjxKzvB8Bj54KC5P7VskqLpjP9U=; b=I7ZoRtVcdiceE0KqjMUh4oAXunfqtssJFcD58ePOgLHvhiBFHckFTmqHmh0vYvaYZ9 ktJ7WAvS/EuKTNm+UXodW65mXdtIcHwd4P1HHw/EIWz0xJFNyqUAiblIcScUTAKoa3SG FzUryobnwCOEYgK5fLOuyIE9CMkxMr4KkxukVYty/ZJljqiCMkWVPSlbZ0WZJMOr8Lnu 9f9h087okO83b0P1AQyLMMG+oVjtHddeuze4a6JpQsVGtSwfrmqILaqPwCkwVJ9HhoYR Y2OzPbfXAizj3340HUnP7yw2+pR5SPRaEEvkhoQZ+WJMjfMucL9RuPdFe6oztCeK6Njc PLiQ== X-Gm-Message-State: AIkVDXIy7l66qaOWgwhBrtjIGUQmui/Xq4RJsUFkQDh46wmplIDqpD5mnE/j87OgaM8rhS3b X-Received: by 10.223.147.100 with SMTP id 91mr263323wro.124.1483978047571; Mon, 09 Jan 2017 08:07:27 -0800 (PST) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id w18sm19656244wme.9.2017.01.09.08.07.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Jan 2017 08:07:26 -0800 (PST) From: Alexandre Bailon To: vinod.koul@intel.com Cc: dmaengine@vger.kernel.org, linux-usb@vger.kernel.org, nsekhar@ti.com, khilman@baylibre.com, ptitiano@baylibre.com, tony@atomide.com, linux-omap@vger.kernel.org, devicetree@vger.kernel.org, robh+dt@kernel.org, b-liu@ti.com, Alexandre Bailon Subject: [PATCH 10/11] dmaengine: cppi41: Fix da8xx interrupt issue Date: Mon, 9 Jan 2017 17:06:55 +0100 Message-Id: <20170109160656.3470-11-abailon@baylibre.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170109160656.3470-1-abailon@baylibre.com> References: <20170109160656.3470-1-abailon@baylibre.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Sometime, after a teardown, interrupts are not fired anymore. This happen because the interrupt handler doesn't re-assert IRQ. Once the teardown complete, the teardown descriptor is moved to completion queue, which is causing an interrupt. But cppi41_tear_down_chan() is called from atomic section, and it polls the queue until it got the teardown descriptor. Then, the interrupt handler is called but it is not able detect the cause of the interrupt and assume the interrupt has been fired by USB core. In that situation, the IRQ won't be re-asserted and interrupts won't work anymore. Add the td_complete variable to detect an interrupt fired by DMA during a teardown, and then re-assert IRQ. Signed-off-by: Alexandre Bailon --- drivers/dma/cppi41.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) -- 2.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index e8470b1..0060391 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -171,6 +171,8 @@ struct cppi41_dd { /* da8xx clock */ struct clk *clk; + + bool td_complete; }; static struct chan_queues am335x_usb_queues_tx[] = { @@ -398,19 +400,29 @@ static irqreturn_t da8xx_cppi41_irq(int irq, void *data) struct cppi41_dd *cdd = data; u32 status; u32 usbss_status; + irqreturn_t ret = IRQ_NONE; status = cppi_readl(cdd->qmgr_mem + QMGR_PEND(0)); if (status & DA8XX_QMGR_PENDING_MASK) - cppi41_irq(cdd); - else - return IRQ_NONE; + ret = cppi41_irq(cdd); + + if (cdd->td_complete) { + /* + * Spurious IRQ caused by teardown. + * DMA interrupts are not maskable, so there is now way + * to prevent it. + * Just ensure that the IRQ will be re-asserted. + */ + cdd->td_complete = false; + ret = IRQ_HANDLED; + } /* Re-assert IRQ if there no usb core interrupts pending */ usbss_status = cppi_readl(cdd->usbss_mem + DA8XX_INTR_SRC_MASKED); - if (!usbss_status) + if (ret == IRQ_HANDLED && !usbss_status) cppi_writel(0, cdd->usbss_mem + DA8XX_END_OF_INTR); - return IRQ_HANDLED; + return ret; } static dma_cookie_t cppi41_tx_submit(struct dma_async_tx_descriptor *tx) @@ -740,6 +752,14 @@ static int cppi41_tear_down_chan(struct cppi41_channel *c) WARN_ON(!desc_phys); } + /* On DA8xx, we are using the PEND0 register to determine if + * the interrupt is generated by DMA. But because the teardown has + * already been popped from completion queue, PEND0 is clear and + * the interrupt handler will assume the interrupt has been fired + * by the USB core. + */ + cdd->td_complete = true; + c->td_queued = 0; c->td_seen = 0; c->td_desc_seen = 0;