From patchwork Sat May 20 21:42:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 9738781 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 32AF0600C8 for ; Sat, 20 May 2017 21:43:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 256772861B for ; Sat, 20 May 2017 21:43:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1A54928633; Sat, 20 May 2017 21:43:40 +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 64CB02861B for ; Sat, 20 May 2017 21:43:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932296AbdETVna (ORCPT ); Sat, 20 May 2017 17:43:30 -0400 Received: from mail-lf0-f54.google.com ([209.85.215.54]:33119 "EHLO mail-lf0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932309AbdETVnZ (ORCPT ); Sat, 20 May 2017 17:43:25 -0400 Received: by mail-lf0-f54.google.com with SMTP id m18so15133200lfj.0 for ; Sat, 20 May 2017 14:43:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LkK0wvFkVDw5StZC/JmYqrjq2SLUQJq93y72T+NUups=; b=Dm4kFOzcst0eqslaw0QQECa/9pIbrRaqfD/Og7oIOk7beUna+Whc++xBqeebu246h0 A1zKouMXR5QgIEl2EpEaQQ9HjhyHO4I8I3rflLq0VhCT9cDNXR1YsTwLWC5TTKvOlxpz CjX+PWaKYVeIEQQis14D7wieVfPtPsR3XMngc= 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=LkK0wvFkVDw5StZC/JmYqrjq2SLUQJq93y72T+NUups=; b=ooEvJDfbOtoxh6WevLGAZKfn6p6vOP3nkFG2cXuxcPBGWnUUH6Dv1iWGQl2BE/KlGI 7kDPt6s0IUc/8/RJP2Gh6OaYaExxjI2qwENTyaNDvDJkiGOlh1l/kqhE1ZHH/KTvavPf fomhqgiZbgBwqTdrNsh228DPCHq3ICHEg6Fj6lzLEZDuk7hLpW727rqzN622e8GnyCmU G3sWsde5vJ5so36uPhcOKBLcICnkIcp4dvdp8IrVRKnTY2gOwGm69uWn3GsTUhUi3vec LU2nPsrf15hkDZU2duIP/V+55jCQT0EhGJ0GWG/rWVL3vblquSowSKfVB40LnP7DOew/ qtIQ== X-Gm-Message-State: AODbwcBh/6Otp5JDwFBvGBf9S7BUgZrOmXJx1IRQyAtmocYtHbMp5kaX WwqBG+WfNLacnFJ3 X-Received: by 10.46.81.17 with SMTP id f17mr4201390ljb.96.1495316587977; Sat, 20 May 2017 14:43:07 -0700 (PDT) Received: from fabina.bredbandsbolaget.se (c-787571d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.117.120]) by smtp.gmail.com with ESMTPSA id e68sm1698029lff.11.2017.05.20.14.43.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 20 May 2017 14:43:06 -0700 (PDT) From: Linus Walleij To: Vinod Koul , dmaengine@vger.kernel.org Cc: Janos Laube , Paulius Zaleckas , linux-arm-kernel@lists.infradead.org, Hans Ulli Kroll , Florian Fainelli , Kuo-Jung Su , Linus Walleij Subject: [PATCH 3/5 v2] dma: pl08x: Make slave engine optional Date: Sat, 20 May 2017 23:42:52 +0200 Message-Id: <20170520214254.21541-3-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170520214254.21541-1-linus.walleij@linaro.org> References: <20170520214254.21541-1-linus.walleij@linaro.org> Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If the vendor data does not specify any signals, we do not have to support slave DMA. Make the registration of the slave DMA engine optional, so we can use this for the FTDMAC020 in the Gemini that only has memcpy support. Signed-off-by: Linus Walleij --- ChangeLog v1->v2: - No changes, just resending. --- drivers/dma/amba-pl08x.c | 128 +++++++++++++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 50 deletions(-) diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index d3d660a36ad7..6ddb029dac50 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -253,8 +253,9 @@ struct pl08x_dma_chan { /** * struct pl08x_driver_data - the local state holder for the PL08x - * @slave: slave engine for this instance + * @slave: optional slave engine for this instance * @memcpy: memcpy engine for this instance + * @has_slave: the PL08x has a slave engine (routed signals) * @base: virtual memory base (remapped) for the PL08x * @adev: the corresponding AMBA (PrimeCell) bus entry * @vd: vendor data for this PL08x variant @@ -269,6 +270,7 @@ struct pl08x_dma_chan { struct pl08x_driver_data { struct dma_device slave; struct dma_device memcpy; + bool has_slave; void __iomem *base; struct amba_device *adev; const struct vendor_data *vd; @@ -705,7 +707,7 @@ static void pl08x_phy_free(struct pl08x_dma_chan *plchan) break; } - if (!next) { + if (!next && pl08x->has_slave) { list_for_each_entry(p, &pl08x->slave.channels, vc.chan.device_node) if (p->state == PL08X_CHAN_WAITING) { next = p; @@ -2085,12 +2087,15 @@ static int pl08x_debugfs_show(struct seq_file *s, void *data) pl08x_state_str(chan->state)); } - seq_printf(s, "\nPL08x virtual slave channels:\n"); - seq_printf(s, "CHANNEL:\tSTATE:\n"); - seq_printf(s, "--------\t------\n"); - list_for_each_entry(chan, &pl08x->slave.channels, vc.chan.device_node) { - seq_printf(s, "%s\t\t%s\n", chan->name, - pl08x_state_str(chan->state)); + if (pl08x->has_slave) { + seq_printf(s, "\nPL08x virtual slave channels:\n"); + seq_printf(s, "CHANNEL:\tSTATE:\n"); + seq_printf(s, "--------\t------\n"); + list_for_each_entry(chan, &pl08x->slave.channels, + vc.chan.device_node) { + seq_printf(s, "%s\t\t%s\n", chan->name, + pl08x_state_str(chan->state)); + } } return 0; @@ -2128,6 +2133,10 @@ static struct dma_chan *pl08x_find_chan_id(struct pl08x_driver_data *pl08x, { struct pl08x_dma_chan *chan; + /* Trying to get a slave channel from something with no slave support */ + if (!pl08x->has_slave) + return NULL; + list_for_each_entry(chan, &pl08x->slave.channels, vc.chan.device_node) { if (chan->signal == id) return &chan->vc.chan; @@ -2265,20 +2274,24 @@ static int pl08x_of_probe(struct amba_device *adev, * for a device and have it's AHB interfaces set up at * translation time. */ - chanp = devm_kcalloc(&adev->dev, - pl08x->vd->signals, - sizeof(struct pl08x_channel_data), - GFP_KERNEL); - if (!chanp) - return -ENOMEM; + if (pl08x->vd->signals) { + chanp = devm_kcalloc(&adev->dev, + pl08x->vd->signals, + sizeof(struct pl08x_channel_data), + GFP_KERNEL); + if (!chanp) + return -ENOMEM; - pd->slave_channels = chanp; - for (i = 0; i < pl08x->vd->signals; i++) { - /* chanp->periph_buses will be assigned at translation */ - chanp->bus_id = kasprintf(GFP_KERNEL, "slave%d", i); - chanp++; + pd->slave_channels = chanp; + for (i = 0; i < pl08x->vd->signals; i++) { + /* + * chanp->periph_buses will be assigned at translation + */ + chanp->bus_id = kasprintf(GFP_KERNEL, "slave%d", i); + chanp++; + } + pd->num_slave_channels = pl08x->vd->signals; } - pd->num_slave_channels = pl08x->vd->signals; pl08x->pd = pd; @@ -2340,24 +2353,34 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) pl08x->memcpy.directions = BIT(DMA_MEM_TO_MEM); pl08x->memcpy.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; - /* Initialize slave engine */ - dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask); - dma_cap_set(DMA_CYCLIC, pl08x->slave.cap_mask); - pl08x->slave.dev = &adev->dev; - pl08x->slave.device_free_chan_resources = pl08x_free_chan_resources; - pl08x->slave.device_prep_dma_interrupt = pl08x_prep_dma_interrupt; - pl08x->slave.device_tx_status = pl08x_dma_tx_status; - pl08x->slave.device_issue_pending = pl08x_issue_pending; - pl08x->slave.device_prep_slave_sg = pl08x_prep_slave_sg; - pl08x->slave.device_prep_dma_cyclic = pl08x_prep_dma_cyclic; - pl08x->slave.device_config = pl08x_config; - pl08x->slave.device_pause = pl08x_pause; - pl08x->slave.device_resume = pl08x_resume; - pl08x->slave.device_terminate_all = pl08x_terminate_all; - pl08x->slave.src_addr_widths = PL80X_DMA_BUSWIDTHS; - pl08x->slave.dst_addr_widths = PL80X_DMA_BUSWIDTHS; - pl08x->slave.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); - pl08x->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; + /* + * Initialize slave engine, if the block has no signals, that means + * we have no slave support. + */ + if (vd->signals) { + pl08x->has_slave = true; + dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask); + dma_cap_set(DMA_CYCLIC, pl08x->slave.cap_mask); + pl08x->slave.dev = &adev->dev; + pl08x->slave.device_free_chan_resources = + pl08x_free_chan_resources; + pl08x->slave.device_prep_dma_interrupt = + pl08x_prep_dma_interrupt; + pl08x->slave.device_tx_status = pl08x_dma_tx_status; + pl08x->slave.device_issue_pending = pl08x_issue_pending; + pl08x->slave.device_prep_slave_sg = pl08x_prep_slave_sg; + pl08x->slave.device_prep_dma_cyclic = pl08x_prep_dma_cyclic; + pl08x->slave.device_config = pl08x_config; + pl08x->slave.device_pause = pl08x_pause; + pl08x->slave.device_resume = pl08x_resume; + pl08x->slave.device_terminate_all = pl08x_terminate_all; + pl08x->slave.src_addr_widths = PL80X_DMA_BUSWIDTHS; + pl08x->slave.dst_addr_widths = PL80X_DMA_BUSWIDTHS; + pl08x->slave.directions = + BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + pl08x->slave.residue_granularity = + DMA_RESIDUE_GRANULARITY_SEGMENT; + } /* Get the platform data */ pl08x->pd = dev_get_platdata(&adev->dev); @@ -2465,13 +2488,15 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) } /* Register slave channels */ - ret = pl08x_dma_init_virtual_channels(pl08x, &pl08x->slave, - pl08x->pd->num_slave_channels, true); - if (ret < 0) { - dev_warn(&pl08x->adev->dev, - "%s failed to enumerate slave channels - %d\n", - __func__, ret); - goto out_no_slave; + if (pl08x->has_slave) { + ret = pl08x_dma_init_virtual_channels(pl08x, &pl08x->slave, + pl08x->pd->num_slave_channels, true); + if (ret < 0) { + dev_warn(&pl08x->adev->dev, + "%s failed to enumerate slave channels - %d\n", + __func__, ret); + goto out_no_slave; + } } ret = dma_async_device_register(&pl08x->memcpy); @@ -2482,12 +2507,14 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) goto out_no_memcpy_reg; } - ret = dma_async_device_register(&pl08x->slave); - if (ret) { - dev_warn(&pl08x->adev->dev, + if (pl08x->has_slave) { + ret = dma_async_device_register(&pl08x->slave); + if (ret) { + dev_warn(&pl08x->adev->dev, "%s failed to register slave as an async device - %d\n", __func__, ret); - goto out_no_slave_reg; + goto out_no_slave_reg; + } } amba_set_drvdata(adev, pl08x); @@ -2501,7 +2528,8 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) out_no_slave_reg: dma_async_device_unregister(&pl08x->memcpy); out_no_memcpy_reg: - pl08x_free_virtual_channels(&pl08x->slave); + if (pl08x->has_slave) + pl08x_free_virtual_channels(&pl08x->slave); out_no_slave: pl08x_free_virtual_channels(&pl08x->memcpy); out_no_memcpy: