From: Geert Uytterhoeven <geert+renesas@glider.be>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Jiri Slaby <jslaby@suse.com>
Cc: Muhammad Hamza Farooq <mfarooq@visteon.com>,
Magnus Damm <magnus.damm@gmail.com>,
Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>,
Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>,
Nobuhiro Iwamatsu <iwamatsu@nigauri.org>,
Yoshihiro Kaneko <ykaneko0929@gmail.com>,
Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>,
Koji Matsuoka <koji.matsuoka.xm@renesas.com>,
Wolfram Sang <wsa@the-dreams.de>,
Guennadi Liakhovetski <g.liakhovetski@gmx.de>,
linux-serial@vger.kernel.org, linux-sh@vger.kernel.org,
Geert Uytterhoeven <geert+renesas@glider.be>
Subject: [PATCH v4 10/10] serial: sh-sci: Add DT support to DMA setup
Date: Fri, 18 Sep 2015 13:08:33 +0200 [thread overview]
Message-ID: <1442574513-20648-11-git-send-email-geert+renesas@glider.be> (raw)
In-Reply-To: <1442574513-20648-1-git-send-email-geert+renesas@glider.be>
Add support for obtaining DMA channel information from the device tree.
This requires switching from the legacy sh_dmae_slave structures with
hardcoded channel numbers and the corresponding filter function to:
1. dma_request_slave_channel_compat(),
- On legacy platforms, dma_request_slave_channel_compat() uses
the passed DMA channel numbers that originate from platform
device data,
- On DT-based platforms, dma_request_slave_channel_compat() will
retrieve the information from DT.
2. and the generic dmaengine_slave_config() configuration method,
which requires filling in DMA register ports and slave bus widths.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
v4:
- Dropped RFC status,
- Moved to end of new series,
v3:
- Moved to end of series, to avoid enabling broken DMA,
v2:
- Add Acked-by.
---
drivers/tty/serial/sh-sci.c | 78 +++++++++++++++++++++++++++------------------
1 file changed, 47 insertions(+), 31 deletions(-)
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index b1d1ce1986e6c064..960e50a97558cff5 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -112,8 +112,6 @@ struct sci_port {
struct scatterlist sg_rx[2];
void *rx_buf[2];
size_t buf_len_rx;
- struct sh_dmae_slave param_tx;
- struct sh_dmae_slave param_rx;
struct work_struct work_tx;
struct timer_list rx_timer;
unsigned int rx_timeout;
@@ -1263,17 +1261,6 @@ static void work_fn_tx(struct work_struct *work)
dma_async_issue_pending(chan);
}
-static bool filter(struct dma_chan *chan, void *slave)
-{
- struct sh_dmae_slave *param = slave;
-
- dev_dbg(chan->device->dev, "%s: slave ID %d\n",
- __func__, param->shdma_slave.slave_id);
-
- chan->private = ¶m->shdma_slave;
- return true;
-}
-
static void rx_timer_fn(unsigned long arg)
{
struct sci_port *s = (struct sci_port *)arg;
@@ -1347,28 +1334,62 @@ static void rx_timer_fn(unsigned long arg)
spin_unlock_irqrestore(&port->lock, flags);
}
+static struct dma_chan *sci_request_dma_chan(struct uart_port *port,
+ enum dma_transfer_direction dir,
+ unsigned int id)
+{
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+ struct dma_slave_config cfg;
+ int ret;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
+ (void *)(unsigned long)id, port->dev,
+ dir == DMA_MEM_TO_DEV ? "tx" : "rx");
+ if (!chan) {
+ dev_warn(port->dev,
+ "dma_request_slave_channel_compat failed\n");
+ return NULL;
+ }
+
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.direction = dir;
+ if (dir == DMA_MEM_TO_DEV) {
+ cfg.dst_addr = port->mapbase +
+ (sci_getreg(port, SCxTDR)->offset << port->regshift);
+ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ } else {
+ cfg.src_addr = port->mapbase +
+ (sci_getreg(port, SCxRDR)->offset << port->regshift);
+ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ }
+
+ ret = dmaengine_slave_config(chan, &cfg);
+ if (ret) {
+ dev_warn(port->dev, "dmaengine_slave_config failed %d\n", ret);
+ dma_release_channel(chan);
+ return NULL;
+ }
+
+ return chan;
+}
+
static void sci_request_dma(struct uart_port *port)
{
struct sci_port *s = to_sci_port(port);
- struct sh_dmae_slave *param;
struct dma_chan *chan;
- dma_cap_mask_t mask;
dev_dbg(port->dev, "%s: port %d\n", __func__, port->line);
- if (s->cfg->dma_slave_tx <= 0 || s->cfg->dma_slave_rx <= 0)
+ if (!port->dev->of_node &&
+ (s->cfg->dma_slave_tx <= 0 || s->cfg->dma_slave_rx <= 0))
return;
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
-
- param = &s->param_tx;
-
- /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */
- param->shdma_slave.slave_id = s->cfg->dma_slave_tx;
-
s->cookie_tx = -EINVAL;
- chan = dma_request_channel(mask, filter, param);
+ chan = sci_request_dma_chan(port, DMA_MEM_TO_DEV, s->cfg->dma_slave_tx);
dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan);
if (chan) {
s->chan_tx = chan;
@@ -1390,12 +1411,7 @@ static void sci_request_dma(struct uart_port *port)
INIT_WORK(&s->work_tx, work_fn_tx);
}
- param = &s->param_rx;
-
- /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */
- param->shdma_slave.slave_id = s->cfg->dma_slave_rx;
-
- chan = dma_request_channel(mask, filter, param);
+ chan = sci_request_dma_chan(port, DMA_DEV_TO_MEM, s->cfg->dma_slave_rx);
dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan);
if (chan) {
unsigned int i;
--
1.9.1
prev parent reply other threads:[~2015-09-18 11:08 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-18 11:08 [PATCH v4 00/10] serial: sh-sci: Add DT DMA support Geert Uytterhoeven
2015-09-18 11:08 ` [PATCH v4 01/10] serial: sh-sci: Shuffle functions around Geert Uytterhoeven
2015-09-18 11:08 ` [PATCH v4 02/10] serial: sh-sci: Get rid of the workqueue to handle receive DMA requests Geert Uytterhoeven
2015-09-18 11:08 ` [PATCH v4 03/10] serial: sh-sci: Submit RX DMA from RX interrupt on (H)SCIF Geert Uytterhoeven
2015-09-18 11:08 ` [PATCH v4 04/10] serial: sh-sci: Stop calling sci_start_rx() from sci_request_dma() Geert Uytterhoeven
2015-09-18 11:08 ` [PATCH v4 05/10] serial: sh-sci: Remove timer on shutdown of port Geert Uytterhoeven
2015-09-18 11:08 ` [PATCH v4 06/10] serial: sh-sci: Redirect port interrupts to CPU _only_ when DMA stops Geert Uytterhoeven
2015-09-18 11:08 ` [PATCH v4 07/10] serial: sh-sci: Call dma_async_issue_pending when transaction completes Geert Uytterhoeven
2015-09-18 11:08 ` [PATCH v4 08/10] serial: sh-sci: Do not terminate DMA engine when race condition occurs Geert Uytterhoeven
2015-09-18 11:08 ` [PATCH v4 09/10] serial: sh-sci: Pause DMA engine and get DMA status again Geert Uytterhoeven
2015-09-18 11:08 ` Geert Uytterhoeven [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1442574513-20648-11-git-send-email-geert+renesas@glider.be \
--to=geert+renesas@glider.be \
--cc=g.liakhovetski@gmx.de \
--cc=gregkh@linuxfoundation.org \
--cc=iwamatsu@nigauri.org \
--cc=jslaby@suse.com \
--cc=kazuya.mizuguchi.ks@renesas.com \
--cc=koji.matsuoka.xm@renesas.com \
--cc=laurent.pinchart+renesas@ideasonboard.com \
--cc=linux-serial@vger.kernel.org \
--cc=linux-sh@vger.kernel.org \
--cc=magnus.damm@gmail.com \
--cc=mfarooq@visteon.com \
--cc=wsa@the-dreams.de \
--cc=ykaneko0929@gmail.com \
--cc=yoshihiro.shimoda.uh@renesas.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).