From patchwork Mon Jan 23 16:48:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Bailon X-Patchwork-Id: 9533103 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 F24FA6020B for ; Mon, 23 Jan 2017 16:48:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E6AB428375 for ; Mon, 23 Jan 2017 16:48:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DB5992841B; Mon, 23 Jan 2017 16:48:27 +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=ham 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 4406028375 for ; Mon, 23 Jan 2017 16:48:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751331AbdAWQs0 (ORCPT ); Mon, 23 Jan 2017 11:48:26 -0500 Received: from mail-wm0-f53.google.com ([74.125.82.53]:36751 "EHLO mail-wm0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751360AbdAWQsZ (ORCPT ); Mon, 23 Jan 2017 11:48:25 -0500 Received: by mail-wm0-f53.google.com with SMTP id c85so141581569wmi.1 for ; Mon, 23 Jan 2017 08:48:24 -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=jyaekH5mElzQReiYKFnidl8c/YIu+UjecT/LJbsCd5w=; b=nmMQ63+4RDIz2ifGXUllv3kpeINinFjiGL1qLyN5tkAtc1T2PnSaRxBK8gMBpHOrxm r6MobjHbpS0fpHUt3oH2balbkFFB4UMBtc9V76BWamQbK8sxLn8NpAJEHZTVELSWXMR4 WcuWUsZLBC+uLb7EiTEBE9yJqcr9Y4ZaX0HQ2f19RlvrobpH6tmAxdV+F1N/halHeIxf zwIHDiNQa8XlV7FNDoj4vUOiOOibek/ssk9I6e6G9+4sd+k6xeuBsyTNZ1TNJQJd6Tlc cxpDGLliu8SubalLSFcWT8IzaUEgfDw0uePu84x/iv+7waicTiJa6+pjuEIJ6bWIWRBO t2gA== 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=jyaekH5mElzQReiYKFnidl8c/YIu+UjecT/LJbsCd5w=; b=cgO3fHNlmja995XVxMvW+zpFrOwv4s0K9DSjGH9BRpA1FNwwgaxQ4te6x66lsYhV92 gZxX7LxRz4BdJX9dvfCtRfDdenFqXqnfyRgjiS9/a+noIteVklqAm1npOk1M4D2OXLUn UroOrJ4ZwezAMDIR8Cqp/ipiHrio0vT9zmiwZOiYQoBZPHW0wcJOboRADkDhdNoIw82T ghtfLewlu4xxO060oHqA59Ly13eArwPU2nHnW61WtMn0kc7wDpF2XoPCG0kcX7/F68bN aP49G8R8zpRLhyPzMP39ol05MCpdTyjP9dkMDv4aSaWw1H6NYOeLncC4m1gBBO/7jdsn 4FYQ== X-Gm-Message-State: AIkVDXLpUgW2K/PKrY70j+GuUcT3iO7N7lrG2Ty14tbzUyOfRWDyKwBiGQj49qbg561K0uZT X-Received: by 10.28.109.218 with SMTP id b87mr13785763wmi.52.1485190103596; Mon, 23 Jan 2017 08:48:23 -0800 (PST) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id y127sm21907054wmg.12.2017.01.23.08.48.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 23 Jan 2017 08:48:23 -0800 (PST) From: Alexandre Bailon To: b-liu@ti.com Cc: vinod.koul@intel.com, dmaengine@vger.kernel.org, nsekhar@ti.com, khilman@baylibre.com, ptitiano@baylibre.com, tony@atomide.com, linux-omap@vger.kernel.org, sergei.shtylyov@cogentembedded.com, Alexandre Bailon Subject: [PATCH v4 6/6] usb: musb: dsps: Manage CPPI 4.1 DMA interrupt in DSPS Date: Mon, 23 Jan 2017 17:48:08 +0100 Message-Id: <20170123164808.27936-7-abailon@baylibre.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170123164808.27936-1-abailon@baylibre.com> References: <20170123164808.27936-1-abailon@baylibre.com> Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Despite the CPPI 4.1 is a generic DMA, it is tied to USB. On the DSPS, CPPI 4.1 interrupt's registers are in USBSS (the MUSB glue). Currently, to enable / disable and clear interrupts, the CPPI 4.1 driver maps and accesses to USBSS's register, which making CPPI 4.1 driver not really generic. Move the interrupt management to DSPS driver. Signed-off-by: Alexandre Bailon --- drivers/dma/cppi41.c | 28 ++++----------- drivers/usb/musb/musb_dsps.c | 81 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 23 deletions(-) diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index d5ba43a..4999e7d 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -79,14 +79,6 @@ #define QMGR_QUEUE_C(n) (0x2008 + (n) * 0x10) #define QMGR_QUEUE_D(n) (0x200c + (n) * 0x10) -/* Glue layer specific */ -/* USBSS / USB AM335x */ -#define USBSS_IRQ_STATUS 0x28 -#define USBSS_IRQ_ENABLER 0x2c -#define USBSS_IRQ_CLEARR 0x30 - -#define USBSS_IRQ_PD_COMP (1 << 2) - /* Packet Descriptor */ #define PD2_ZERO_LENGTH (1 << 19) @@ -288,14 +280,8 @@ static irqreturn_t cppi41_irq(int irq, void *data) { struct cppi41_dd *cdd = data; struct cppi41_channel *c; - u32 status; int i; - status = cppi_readl(cdd->usbss_mem + USBSS_IRQ_STATUS); - if (!(status & USBSS_IRQ_PD_COMP)) - return IRQ_NONE; - cppi_writel(status, cdd->usbss_mem + USBSS_IRQ_STATUS); - for (i = QMGR_PENDING_SLOT_Q(FIST_COMPLETION_QUEUE); i < QMGR_NUM_PEND; i++) { u32 val; @@ -599,6 +585,7 @@ static void cppi41_compute_td_desc(struct cppi41_desc *d) static int cppi41_tear_down_chan(struct cppi41_channel *c) { + struct dmaengine_result abort_result; struct cppi41_dd *cdd = c->cdd; struct cppi41_desc *td; u32 reg; @@ -682,6 +669,12 @@ static int cppi41_tear_down_chan(struct cppi41_channel *c) c->td_seen = 0; c->td_desc_seen = 0; cppi_writel(0, c->gcr_reg); + + /* Invoke the callback to do the necessary clean-up */ + abort_result.result = DMA_TRANS_ABORTED; + dma_cookie_complete(&c->txd); + dmaengine_desc_get_callback_invoke(&c->txd, &abort_result); + return 0; } @@ -1044,8 +1037,6 @@ static int cppi41_dma_probe(struct platform_device *pdev) goto err_irq; } - cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); - ret = devm_request_irq(&pdev->dev, irq, glue_info->isr, IRQF_SHARED, dev_name(dev), cdd); if (ret) @@ -1069,7 +1060,6 @@ static int cppi41_dma_probe(struct platform_device *pdev) dma_async_device_unregister(&cdd->ddev); err_dma_reg: err_irq: - cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); cleanup_chans(cdd); err_chans: deinit_cppi41(dev, cdd); @@ -1097,7 +1087,6 @@ static int cppi41_dma_remove(struct platform_device *pdev) of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&cdd->ddev); - cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); devm_free_irq(&pdev->dev, cdd->irq, cdd); cleanup_chans(cdd); deinit_cppi41(&pdev->dev, cdd); @@ -1116,7 +1105,6 @@ static int __maybe_unused cppi41_suspend(struct device *dev) struct cppi41_dd *cdd = dev_get_drvdata(dev); cdd->dma_tdfdq = cppi_readl(cdd->ctrl_mem + DMA_TDFDQ); - cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); disable_sched(cdd); return 0; @@ -1142,8 +1130,6 @@ static int __maybe_unused cppi41_resume(struct device *dev) cppi_writel(QMGR_SCRATCH_SIZE, cdd->qmgr_mem + QMGR_LRAM_SIZE); cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM1_BASE); - cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); - return 0; } diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 9f125e1..461bc09 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -121,6 +121,7 @@ struct dsps_glue { struct timer_list timer; /* otg_workaround timer */ unsigned long last_timer; /* last timer data for each instance */ bool sw_babble_enabled; + void __iomem *usbss_base; struct dsps_context context; struct debugfs_regset32 regset; @@ -145,6 +146,13 @@ static const struct debugfs_reg32 dsps_musb_regs[] = { { "mode", 0xe8 }, }; +/* USBSS / USB AM335x */ +#define USBSS_IRQ_STATUS 0x28 +#define USBSS_IRQ_ENABLER 0x2c +#define USBSS_IRQ_CLEARR 0x30 + +#define USBSS_IRQ_PD_COMP (1 << 2) + /** * dsps_musb_enable - enable interrupts */ @@ -619,14 +627,76 @@ static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) } } +#ifdef CONFIG_USB_TI_CPPI41_DMA +static void dsps_dma_controller_callback(struct dma_controller *c) +{ + struct musb *musb = c->musb; + struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent); + void __iomem *usbss_base = glue->usbss_base; + u32 status; + + status = musb_readl(usbss_base, USBSS_IRQ_STATUS); + if (status & USBSS_IRQ_PD_COMP) + musb_writel(usbss_base, USBSS_IRQ_STATUS, USBSS_IRQ_PD_COMP); +} + +static struct dma_controller * +dsps_dma_controller_create(struct musb *musb, void __iomem *base) +{ + struct dma_controller *controller; + struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent); + void __iomem *usbss_base = glue->usbss_base; + + controller = cppi41_dma_controller_create(musb, base); + if (IS_ERR_OR_NULL(controller)) + return controller; + + musb_writel(usbss_base, USBSS_IRQ_ENABLER, USBSS_IRQ_PD_COMP); + controller->dma_callback = dsps_dma_controller_callback; + + return controller; +} + +static void dsps_dma_controller_destroy(struct dma_controller *c) +{ + struct musb *musb = c->musb; + struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent); + void __iomem *usbss_base = glue->usbss_base; + + musb_writel(usbss_base, USBSS_IRQ_CLEARR, USBSS_IRQ_PD_COMP); + cppi41_dma_controller_destroy(c); +} + +#ifdef CONFIG_PM_SLEEP +static void dsps_dma_controller_suspend(struct dsps_glue *glue) +{ + void __iomem *usbss_base = glue->usbss_base; + + musb_writel(usbss_base, USBSS_IRQ_CLEARR, USBSS_IRQ_PD_COMP); +} + +static void dsps_dma_controller_resume(struct dsps_glue *glue) +{ + void __iomem *usbss_base = glue->usbss_base; + + musb_writel(usbss_base, USBSS_IRQ_ENABLER, USBSS_IRQ_PD_COMP); +} +#endif +#else /* CONFIG_USB_TI_CPPI41_DMA */ +#ifdef CONFIG_PM_SLEEP +static void dsps_dma_controller_suspend(struct dsps_glue *glue) {} +static void dsps_dma_controller_resume(struct dsps_glue *glue) {} +#endif +#endif /* CONFIG_USB_TI_CPPI41_DMA */ + static struct musb_platform_ops dsps_ops = { .quirks = MUSB_DMA_CPPI41 | MUSB_INDEXED_EP, .init = dsps_musb_init, .exit = dsps_musb_exit, #ifdef CONFIG_USB_TI_CPPI41_DMA - .dma_init = cppi41_dma_controller_create, - .dma_exit = cppi41_dma_controller_destroy, + .dma_init = dsps_dma_controller_create, + .dma_exit = dsps_dma_controller_destroy, #endif .enable = dsps_musb_enable, .disable = dsps_musb_disable, @@ -792,6 +862,9 @@ static int dsps_probe(struct platform_device *pdev) glue->dev = &pdev->dev; glue->wrp = wrp; + glue->usbss_base = of_iomap(pdev->dev.parent->of_node, 0); + if (!glue->usbss_base) + return -ENXIO; platform_set_drvdata(pdev, glue); pm_runtime_enable(&pdev->dev); @@ -880,6 +953,8 @@ static int dsps_suspend(struct device *dev) glue->context.tx_mode = musb_readl(mbase, wrp->tx_mode); glue->context.rx_mode = musb_readl(mbase, wrp->rx_mode); + dsps_dma_controller_suspend(glue); + return 0; } @@ -893,6 +968,8 @@ static int dsps_resume(struct device *dev) if (!musb) return 0; + dsps_dma_controller_resume(glue); + mbase = musb->ctrl_base; musb_writel(mbase, wrp->control, glue->context.control); musb_writel(mbase, wrp->epintr_set, glue->context.epintr);