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: 9505373 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CF08E606E1 for ; Mon, 9 Jan 2017 16:09:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C19B528474 for ; Mon, 9 Jan 2017 16:09:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B692728497; Mon, 9 Jan 2017 16:09:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE47C28474 for ; Mon, 9 Jan 2017 16:09:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1762356AbdAIQIE (ORCPT ); Mon, 9 Jan 2017 11:08:04 -0500 Received: from mail-wm0-f41.google.com ([74.125.82.41]:35537 "EHLO mail-wm0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S970259AbdAIQH2 (ORCPT ); Mon, 9 Jan 2017 11:07:28 -0500 Received: by mail-wm0-f41.google.com with SMTP id a197so102722038wmd.0 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=LrkRr2ZrQej578i7+9Z7GIC/fRrZyhVJRiBQpRtiKLwMSXRq7o8Id76C1Sn1n3QK1g 3yD6vIuZokax51q5tB9sU7yKeP2L/jruQGrgqhfnvn3BFEQAuxNjGWHVNWIBGkiuf0ym RW+sgi6p14oK+asWIk1L4R4elpv3mLpQzpkg1pwvzlPG2vSaeJOiBprfQJZGckope6iE 8fSxsfSTWNIb8grFHxEXIejBA+wT+SFF3EWXgG82OJgC/zJpRAdJn2EhKyjiJmzLf4rr ChT40M6XECWIVAh3egMPseasexw3JxkVe+6A5PPeHJ5gL5WnkueTajqQKilHi4Eh7C0o lPkQ== X-Gm-Message-State: AIkVDXJ6EehgXJZrO3QHI3krzy9rBjvBP/ypEt0stc8p4WRs0NCb1CnDTpH5293NY//J31VL 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-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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(-) 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;