From patchwork Tue Jan 17 13:45:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Bailon X-Patchwork-Id: 9521031 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 5722C601C3 for ; Tue, 17 Jan 2017 13:53:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 384F428564 for ; Tue, 17 Jan 2017 13:53:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2CFDA2856A; Tue, 17 Jan 2017 13:53:36 +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 C5A2C28564 for ; Tue, 17 Jan 2017 13:53:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751042AbdAQNxe (ORCPT ); Tue, 17 Jan 2017 08:53:34 -0500 Received: from mail-wm0-f51.google.com ([74.125.82.51]:36817 "EHLO mail-wm0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750939AbdAQNxd (ORCPT ); Tue, 17 Jan 2017 08:53:33 -0500 Received: by mail-wm0-f51.google.com with SMTP id c85so200881614wmi.1 for ; Tue, 17 Jan 2017 05:53:33 -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=q2NL+bi0peA+W7j8XaoEWpJ3Dd0spQTD0P4xYm4tN9o=; b=PgGZrppY48XRWXAgW91BNPYdpF6zpJJ5ImkQtKy8XmbyBnrQk9hhL5NifMOfqoUGr8 uL/WAPeO3HMQS1P5Z4ZNKly4aAKd8T3LXFDADf6Xm/Rake91V6EB99SYN9aD0HurS8op w7yK8jqZWWGvZCW+o8BPI+CuZBxbKNg4md2VIxXyjB0GFBuNc5o1Ats0V981YZ9N+L+Z XaEThyKYX+rfYhIt5xDf8XC1MaojgfYZjZXQdSSQUMOszwRMFufhFJTB2tBWy9csrJ0z tEBpYQEUcs5UB/2DFxyrAq4GxubFHgGJQ8UZ7mhX4Y+5WZZAU0NGtRlo7wAc99YrQieH nxYw== 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=q2NL+bi0peA+W7j8XaoEWpJ3Dd0spQTD0P4xYm4tN9o=; b=MN3NwmotNyldpROnR612XZn18UjF23c6yjxs0C6z7YrAoemMdlc0KT9s6HW6VO3EJe QAWri4SDj8WSTSHN6UmUIdJRsXws8Snhjim8taTyREnP9ZaBkP7JwE21gCnZ0x881ebm oNTNVx5AnvU+3tI5o07lEVfxZgDWwhlMFx6h/JcXsQVhCmuALJ699zudDuXLi8AU3A/n UDoJQaofi74exO0JHXjuyfWqHJdNxKC2gIWSFgZEhajhQ0zuKAPJoqXZxJh7Ivi7cQc3 g3UECrPHkWW9nC2KRl3GLFuctklajl+NRAVtSosdu/LqxJakavlziGDFZpeEsBGvH43v 6wYw== X-Gm-Message-State: AIkVDXKPBZIqSnA92r+V5mNVzrctqqTzIJJamSUW/E/WM1dwLQJ1fOadsgpSGKZbLrUE+bV8 X-Received: by 10.28.15.2 with SMTP id 2mr17972592wmp.66.1484660749331; Tue, 17 Jan 2017 05:45:49 -0800 (PST) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id l187sm37064811wml.6.2017.01.17.05.45.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 17 Jan 2017 05:45:48 -0800 (PST) From: Alexandre Bailon To: vinod.koul@intel.com, b-liu@ti.com, robh+dt@kernel.org Cc: 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, devicetree@vger.kernel.org, Alexandre Bailon Subject: [PATCH v2 1/7] usb: musb: dsps: Manage CPPI 4.1 DMA interrupt in dsps Date: Tue, 17 Jan 2017 14:45:34 +0100 Message-Id: <20170117134540.9988-2-abailon@baylibre.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170117134540.9988-1-abailon@baylibre.com> References: <20170117134540.9988-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 | 73 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 78 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..2a20eef 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,68 @@ static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) } } +static void dsps_dma_controller_callback(struct musb *musb); + +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)) { + musb_writel(usbss_base, USBSS_IRQ_ENABLER, USBSS_IRQ_PD_COMP); + cppi41_register_dma_callback(controller, + dsps_dma_controller_callback); + } + + return controller; +} + +static void dsps_dma_controller_destroy(struct dma_controller *c) +{ + struct musb *musb = cppi41_dma_controller_to_musb(c); + 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); +} + +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); +} + +static void dsps_dma_controller_callback(struct musb *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 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 +854,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 +945,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 +960,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);