From patchwork Mon Jul 1 08:39:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Genoud X-Patchwork-Id: 2806431 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6709E9F3EB for ; Mon, 1 Jul 2013 08:44:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2B22020177 for ; Mon, 1 Jul 2013 08:44:41 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 751EB20174 for ; Mon, 1 Jul 2013 08:44:39 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UtZfk-0003Lh-Po; Mon, 01 Jul 2013 08:41:23 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UtZfE-0003LZ-E7; Mon, 01 Jul 2013 08:40:48 +0000 Received: from mail-we0-x231.google.com ([2a00:1450:400c:c03::231]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UtZer-0003Fc-Ft for linux-arm-kernel@lists.infradead.org; Mon, 01 Jul 2013 08:40:28 +0000 Received: by mail-we0-f177.google.com with SMTP id m19so2913422wev.8 for ; Mon, 01 Jul 2013 01:40:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=1qQGzrqxDzPAE0yV+/nQ2Pn9hDLWAXyEg8ezTgPaeFo=; b=y/JpCdoBDnLcH1k4a1sgE9NU+/JE4qerwNILGeqoAwmnZ7sKL3QFD1VWbXiy6plV7Q yI3TFsEMBZR5j1vdXkkRnSu1clSPkD7/2yzV7UoxprvY0877IQd9bZ4gFKnTqBJCo4OR nwin7RzsTkVeffyks81k0L4k0GWo0Q580P/v2LEQtwXgl7X3RSBVj4SYsYRL9ssjCym+ kOdOm6B/XrHszutdvQ952vhkE3nt0opQfqOsVfgUXLltn11rrIHql2SiyWIglEOwMtGM tT8/IY3IZvgeQpTI0QhqfsVFVG7EB9N4jpe60GhWSCzS9vLNKURTF3zvfwxjiTfX5/s+ xUiQ== X-Received: by 10.180.7.164 with SMTP id k4mr11249688wia.40.1372668000408; Mon, 01 Jul 2013 01:40:00 -0700 (PDT) Received: from lnx-rg.pr (lyon.paratronic.fr. [213.41.177.106]) by mx.google.com with ESMTPSA id h8sm14786574wie.1.2013.07.01.01.39.58 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 01 Jul 2013 01:39:59 -0700 (PDT) From: Richard Genoud To: devicetree-discuss@lists.ozlabs.org Subject: [RFC PATCH 01/13] misc: atmel_ssc: add device tree DMA support Date: Mon, 1 Jul 2013 10:39:26 +0200 Message-Id: <1372667978-4718-2-git-send-email-richard.genoud@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1372667978-4718-1-git-send-email-richard.genoud@gmail.com> References: <1372667978-4718-1-git-send-email-richard.genoud@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130701_044025_759302_7999992A X-CRM114-Status: GOOD ( 18.36 ) X-Spam-Score: -2.0 (--) Cc: Richard Genoud , Nicolas Ferre , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The ssc device has to fill the at_dma_slave structure with the device tree informations. Doing a of_dma_request_slave_channel()+dma_release_channel() for that seems wrong (or at least not very clean). Signed-off-by: Richard Genoud --- drivers/misc/atmel-ssc.c | 56 +++++++++++++++++++++++++++++++ include/linux/atmel-ssc.h | 2 ++ include/linux/platform_data/dma-atmel.h | 2 ++ 3 files changed, 60 insertions(+) diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index f7b90661..3afbd82 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -19,7 +19,9 @@ #include #include +#include #include +#include /* Serialize access to ssc_list and user count */ static DEFINE_SPINLOCK(user_lock); @@ -127,12 +129,57 @@ static inline const struct atmel_ssc_platform_data * __init platform_get_device_id(pdev)->driver_data; } +static int atmel_ssc_get_dma_data(struct device_node *np, + struct at_dma_slave *sdata) +{ + struct dma_chan *chan; + struct at_dma_slave *rx_data; + int err = -1; + + /* + * FIXME: this is clearly not the right way to do it. + * In order to fill struct at_dma_slave with both rx and tx data, + * we request and release both channels. + * Et voila ! We've got all the whole structure ! + * upside: it works(R) + * downside: feels wrong, dirty, not optimized... + */ + chan = of_dma_request_slave_channel(np, "tx"); + if (!chan) + return err; + + if (chan->private) + memcpy(sdata, chan->private, sizeof(*sdata)); + else + goto out; + + dma_release_channel(chan); + + chan = of_dma_request_slave_channel(np, "rx"); + if (!chan) + goto out; + + if (chan->private) { + rx_data = chan->private; + sdata->cfg &= ~(ATC_SRC_PER_MSB(0xff) | ATC_SRC_PER(0xff)); + sdata->cfg |= ATC_GET_SRC_ID(rx_data->cfg); + err = 0; + } + +out: + if (chan) + dma_release_channel(chan); + + return err; +} + static int ssc_probe(struct platform_device *pdev) { struct resource *regs; struct ssc_device *ssc; const struct atmel_ssc_platform_data *plat_dat; struct pinctrl *pinctrl; + struct device_node *of = pdev->dev.of_node; pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) { @@ -166,6 +213,15 @@ static int ssc_probe(struct platform_device *pdev) return -ENXIO; } + /* populate platform_data from device tree */ + if (ssc->pdata && ssc->pdata->use_dma && of) { + if (atmel_ssc_get_dma_data(of, &ssc->pdata->dma_slave)) { + dev_err(&pdev->dev, "could not get DMA\n"); + return -EINVAL; + } + } + ssc->pdev->dev.platform_data = &ssc->pdata->dma_slave; + /* disable all interrupts */ clk_prepare_enable(ssc->clk); ssc_writel(ssc->regs, IDR, -1); diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index deb0ae5..80c83ee 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h @@ -1,12 +1,14 @@ #ifndef __INCLUDE_ATMEL_SSC_H #define __INCLUDE_ATMEL_SSC_H +#include #include #include #include struct atmel_ssc_platform_data { int use_dma; + struct at_dma_slave dma_slave; }; struct ssc_device { diff --git a/include/linux/platform_data/dma-atmel.h b/include/linux/platform_data/dma-atmel.h index e95f19c..0d8b9d6 100644 --- a/include/linux/platform_data/dma-atmel.h +++ b/include/linux/platform_data/dma-atmel.h @@ -44,11 +44,13 @@ struct at_dma_slave { #define ATC_SRC_H2SEL_SW (0x0 << 9) #define ATC_SRC_H2SEL_HW (0x1 << 9) #define ATC_SRC_PER_MSB(h) (ATC_PER_MSB(h) << 10) /* Channel src rq (most significant bits) */ +#define ATC_GET_SRC_ID(h) ((((h) >> 6) & 0x3U) | ((h) & 0xFU)) /* Retrieve channel src id */ #define ATC_DST_REP (0x1 << 12) /* Destination Replay Mod */ #define ATC_DST_H2SEL (0x1 << 13) /* Destination Handshaking Mod */ #define ATC_DST_H2SEL_SW (0x0 << 13) #define ATC_DST_H2SEL_HW (0x1 << 13) #define ATC_DST_PER_MSB(h) (ATC_PER_MSB(h) << 14) /* Channel dst rq (most significant bits) */ +#define ATC_GET_DST_ID(h) ((((h) >> 10) & 0x3U) | (((h) >> 4) & 0xFU)) /* Retrieve channel dst id */ #define ATC_SOD (0x1 << 16) /* Stop On Done */ #define ATC_LOCK_IF (0x1 << 20) /* Interface Lock */ #define ATC_LOCK_B (0x1 << 21) /* AHB Bus Lock */