All of lore.kernel.org
 help / color / mirror / Atom feed
From: lars@metafoo.de (Lars-Peter Clausen)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2] dma: Add Xilinx AXI Video Direct Memory Access Engine driver support
Date: Thu, 23 Jan 2014 12:25:22 +0100	[thread overview]
Message-ID: <52E0FC22.8060903@metafoo.de> (raw)
In-Reply-To: <1390409565-4200-2-git-send-email-sthokal@xilinx.com>

On 01/22/2014 05:52 PM, Srikanth Thokala wrote:
[...]
> +/**
> + * xilinx_vdma_device_control - Configure DMA channel of the device
> + * @dchan: DMA Channel pointer
> + * @cmd: DMA control command
> + * @arg: Channel configuration
> + *
> + * Return: '0' on success and failure value on error
> + */
> +static int xilinx_vdma_device_control(struct dma_chan *dchan,
> +				      enum dma_ctrl_cmd cmd, unsigned long arg)
> +{
> +	struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
> +
> +	switch (cmd) {
> +	case DMA_TERMINATE_ALL:
> +		xilinx_vdma_terminate_all(chan);
> +		return 0;
> +	case DMA_SLAVE_CONFIG:
> +		return xilinx_vdma_slave_config(chan,
> +					(struct xilinx_vdma_config *)arg);

You really shouldn't be overloading the generic API with your own semantics.
DMA_SLAVE_CONFIG should take a dma_slave_config and nothing else.

> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
[...]
> +
> +	/* Request the interrupt */
> +	chan->irq = irq_of_parse_and_map(node, 0);
> +	err = devm_request_irq(xdev->dev, chan->irq, xilinx_vdma_irq_handler,
> +			       IRQF_SHARED, "xilinx-vdma-controller", chan);

This is a clasic example of where to not use devm_request_irq. 'chan' is
accessed in the interrupt handler, but if you use devm_request_irq 'chan'
will be freed before the interrupt handler has been released, which means
there is now a race condition where the interrupt handler can access already
freed memory.

> +	if (err) {
> +		dev_err(xdev->dev, "unable to request IRQ\n");
> +		return err;
> +	}
> +
> +	/* Initialize the DMA channel and add it to the DMA engine channels
> +	 * list.
> +	 */
> +	chan->common.device = &xdev->common;
> +
> +	list_add_tail(&chan->common.device_node, &xdev->common.channels);
> +	xdev->chan[chan->id] = chan;
> +
> +	/* Reset the channel */
> +	err = xilinx_vdma_chan_reset(chan);
> +	if (err < 0) {
> +		dev_err(xdev->dev, "Reset channel failed\n");
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * struct of_dma_filter_xilinx_args - Channel filter args
> + * @dev: DMA device structure
> + * @chan_id: Channel id
> + */
> +struct of_dma_filter_xilinx_args {
> +	struct dma_device *dev;
> +	u32 chan_id;
> +};
> +
> +/**
> + * xilinx_vdma_dt_filter - VDMA channel filter function
> + * @chan: DMA channel pointer
> + * @param: Filter match value
> + *
> + * Return: true/false based on the result
> + */
> +static bool xilinx_vdma_dt_filter(struct dma_chan *chan, void *param)
> +{
> +	struct of_dma_filter_xilinx_args *args = param;
> +
> +	return chan->device == args->dev && chan->chan_id == args->chan_id;
> +}
> +
> +/**
> + * of_dma_xilinx_xlate - Translation function
> + * @dma_spec: Pointer to DMA specifier as found in the device tree
> + * @ofdma: Pointer to DMA controller data
> + *
> + * Return: DMA channel pointer on success and NULL on error
> + */
> +static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
> +						struct of_dma *ofdma)
> +{
> +	struct of_dma_filter_xilinx_args args;
> +	dma_cap_mask_t cap;
> +
> +	args.dev = ofdma->of_dma_data;
> +	if (!args.dev)
> +		return NULL;
> +
> +	if (dma_spec->args_count != 1)
> +		return NULL;
> +
> +	dma_cap_zero(cap);
> +	dma_cap_set(DMA_SLAVE, cap);
> +
> +	args.chan_id = dma_spec->args[0];
> +
> +	return dma_request_channel(cap, xilinx_vdma_dt_filter, &args);

There is a new helper function called dma_get_slave_channel, which makes
this much easier. Take a look at the k3dma.c driver for an example.
> +}

WARNING: multiple messages have this Message-ID (diff)
From: Lars-Peter Clausen <lars@metafoo.de>
To: Srikanth Thokala <sthokal@xilinx.com>
Cc: dan.j.williams@intel.com, vinod.koul@intel.com,
	michal.simek@xilinx.com, grant.likely@linaro.org,
	robh+dt@kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	dmaengine@vger.kernel.org
Subject: Re: [PATCH v2] dma: Add Xilinx AXI Video Direct Memory Access Engine driver support
Date: Thu, 23 Jan 2014 12:25:22 +0100	[thread overview]
Message-ID: <52E0FC22.8060903@metafoo.de> (raw)
In-Reply-To: <1390409565-4200-2-git-send-email-sthokal@xilinx.com>

On 01/22/2014 05:52 PM, Srikanth Thokala wrote:
[...]
> +/**
> + * xilinx_vdma_device_control - Configure DMA channel of the device
> + * @dchan: DMA Channel pointer
> + * @cmd: DMA control command
> + * @arg: Channel configuration
> + *
> + * Return: '0' on success and failure value on error
> + */
> +static int xilinx_vdma_device_control(struct dma_chan *dchan,
> +				      enum dma_ctrl_cmd cmd, unsigned long arg)
> +{
> +	struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
> +
> +	switch (cmd) {
> +	case DMA_TERMINATE_ALL:
> +		xilinx_vdma_terminate_all(chan);
> +		return 0;
> +	case DMA_SLAVE_CONFIG:
> +		return xilinx_vdma_slave_config(chan,
> +					(struct xilinx_vdma_config *)arg);

You really shouldn't be overloading the generic API with your own semantics.
DMA_SLAVE_CONFIG should take a dma_slave_config and nothing else.

> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
[...]
> +
> +	/* Request the interrupt */
> +	chan->irq = irq_of_parse_and_map(node, 0);
> +	err = devm_request_irq(xdev->dev, chan->irq, xilinx_vdma_irq_handler,
> +			       IRQF_SHARED, "xilinx-vdma-controller", chan);

This is a clasic example of where to not use devm_request_irq. 'chan' is
accessed in the interrupt handler, but if you use devm_request_irq 'chan'
will be freed before the interrupt handler has been released, which means
there is now a race condition where the interrupt handler can access already
freed memory.

> +	if (err) {
> +		dev_err(xdev->dev, "unable to request IRQ\n");
> +		return err;
> +	}
> +
> +	/* Initialize the DMA channel and add it to the DMA engine channels
> +	 * list.
> +	 */
> +	chan->common.device = &xdev->common;
> +
> +	list_add_tail(&chan->common.device_node, &xdev->common.channels);
> +	xdev->chan[chan->id] = chan;
> +
> +	/* Reset the channel */
> +	err = xilinx_vdma_chan_reset(chan);
> +	if (err < 0) {
> +		dev_err(xdev->dev, "Reset channel failed\n");
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * struct of_dma_filter_xilinx_args - Channel filter args
> + * @dev: DMA device structure
> + * @chan_id: Channel id
> + */
> +struct of_dma_filter_xilinx_args {
> +	struct dma_device *dev;
> +	u32 chan_id;
> +};
> +
> +/**
> + * xilinx_vdma_dt_filter - VDMA channel filter function
> + * @chan: DMA channel pointer
> + * @param: Filter match value
> + *
> + * Return: true/false based on the result
> + */
> +static bool xilinx_vdma_dt_filter(struct dma_chan *chan, void *param)
> +{
> +	struct of_dma_filter_xilinx_args *args = param;
> +
> +	return chan->device == args->dev && chan->chan_id == args->chan_id;
> +}
> +
> +/**
> + * of_dma_xilinx_xlate - Translation function
> + * @dma_spec: Pointer to DMA specifier as found in the device tree
> + * @ofdma: Pointer to DMA controller data
> + *
> + * Return: DMA channel pointer on success and NULL on error
> + */
> +static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
> +						struct of_dma *ofdma)
> +{
> +	struct of_dma_filter_xilinx_args args;
> +	dma_cap_mask_t cap;
> +
> +	args.dev = ofdma->of_dma_data;
> +	if (!args.dev)
> +		return NULL;
> +
> +	if (dma_spec->args_count != 1)
> +		return NULL;
> +
> +	dma_cap_zero(cap);
> +	dma_cap_set(DMA_SLAVE, cap);
> +
> +	args.chan_id = dma_spec->args[0];
> +
> +	return dma_request_channel(cap, xilinx_vdma_dt_filter, &args);

There is a new helper function called dma_get_slave_channel, which makes
this much easier. Take a look at the k3dma.c driver for an example.
> +}

  parent reply	other threads:[~2014-01-23 11:25 UTC|newest]

Thread overview: 90+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-22 16:52 [PATCH v2] Add Xilinx AXI Video DMA Engine driver Srikanth Thokala
2014-01-22 16:52 ` Srikanth Thokala
2014-01-22 16:52 ` Srikanth Thokala
2014-01-22 16:52 ` [PATCH v2] dma: Add Xilinx AXI Video Direct Memory Access Engine driver support Srikanth Thokala
2014-01-22 16:52   ` Srikanth Thokala
2014-01-22 21:30   ` Levente Kurusa
2014-01-22 21:30     ` Levente Kurusa
2014-01-22 21:30     ` Levente Kurusa
2014-01-23 17:35     ` Srikanth Thokala
2014-01-23 17:35       ` Srikanth Thokala
2014-01-23 17:35       ` Srikanth Thokala
2014-01-23 11:25   ` Lars-Peter Clausen [this message]
2014-01-23 11:25     ` Lars-Peter Clausen
2014-01-23 13:38     ` Shevchenko, Andriy
2014-01-23 13:38       ` Shevchenko, Andriy
2014-01-23 13:38       ` Shevchenko, Andriy
2014-01-23 13:50       ` Lars-Peter Clausen
2014-01-23 13:50         ` Lars-Peter Clausen
2014-01-23 13:50         ` Lars-Peter Clausen
2014-01-23 14:00         ` Andy Shevchenko
2014-01-23 14:00           ` Andy Shevchenko
2014-01-23 14:00           ` Andy Shevchenko
2014-01-23 14:07           ` Lars-Peter Clausen
2014-01-23 14:07             ` Lars-Peter Clausen
2014-01-23 14:07             ` Lars-Peter Clausen
2014-01-26 14:03             ` Vinod Koul
2014-01-26 14:03               ` Vinod Koul
2014-01-26 14:03               ` Vinod Koul
2014-01-26 17:41               ` Lars-Peter Clausen
2014-01-26 17:41                 ` Lars-Peter Clausen
2014-01-24 11:16     ` Srikanth Thokala
2014-01-24 11:16       ` Srikanth Thokala
2014-01-24 13:24       ` Lars-Peter Clausen
2014-01-24 13:24         ` Lars-Peter Clausen
2014-01-24 13:24         ` Lars-Peter Clausen
2014-01-26 13:59         ` Vinod Koul
2014-01-26 13:59           ` Vinod Koul
2014-01-26 17:39           ` Lars-Peter Clausen
2014-01-26 17:39             ` Lars-Peter Clausen
2014-01-26 17:39             ` Lars-Peter Clausen
2014-01-27 13:12             ` Srikanth Thokala
2014-01-27 13:12               ` Srikanth Thokala
2014-01-28  3:13               ` Vinod Koul
2014-01-28  3:13                 ` Vinod Koul
2014-01-31  6:51                 ` Srikanth Thokala
2014-01-31  6:51                   ` Srikanth Thokala
2014-01-31  6:51                   ` Srikanth Thokala
2014-02-05 16:25                   ` Srikanth Thokala
2014-02-05 16:25                     ` Srikanth Thokala
2014-02-05 16:30                     ` Lars-Peter Clausen
2014-02-05 16:30                       ` Lars-Peter Clausen
2014-02-05 16:30                       ` Lars-Peter Clausen
2014-02-06 13:34                       ` Srikanth Thokala
2014-02-06 13:34                         ` Srikanth Thokala
2014-02-06 13:34                         ` Srikanth Thokala
2014-02-06 15:53                         ` Lars-Peter Clausen
2014-02-06 15:53                           ` Lars-Peter Clausen
2014-02-06 15:53                           ` Lars-Peter Clausen
2014-02-10 12:51                           ` Srikanth Thokala
2014-02-10 12:51                             ` Srikanth Thokala
2014-01-28  3:09             ` Vinod Koul
2014-01-28  3:09               ` Vinod Koul
2014-01-28  3:09               ` Vinod Koul
2014-01-27 11:06           ` Srikanth Thokala
2014-01-27 11:06             ` Srikanth Thokala
2014-01-27 11:06             ` Srikanth Thokala
2014-01-31  6:52             ` Srikanth Thokala
2014-01-31  6:52               ` Srikanth Thokala
2014-01-31  6:52               ` Srikanth Thokala
2014-02-04  5:28               ` Vinod Koul
2014-02-04  5:28                 ` Vinod Koul
2014-02-04  5:28                 ` Vinod Koul
2014-02-04 10:35                 ` Srikanth Thokala
2014-02-04 10:35                   ` Srikanth Thokala
2014-02-04 10:35                   ` Srikanth Thokala
2014-01-31 17:44         ` Andy Gross
2014-01-31 17:44           ` Andy Gross
2014-02-01 18:23           ` Lars-Peter Clausen
2014-02-01 18:23             ` Lars-Peter Clausen
2014-02-01 18:23             ` Lars-Peter Clausen
2014-01-23 13:32   ` Andy Shevchenko
2014-01-23 13:32     ` Andy Shevchenko
2014-01-23 17:52     ` Srikanth Thokala
2014-01-23 17:52       ` Srikanth Thokala
2014-01-23 17:52       ` Srikanth Thokala
2014-01-26 14:24   ` Vinod Koul
2014-01-26 14:24     ` Vinod Koul
2014-01-26 17:46     ` Lars-Peter Clausen
2014-01-26 17:46       ` Lars-Peter Clausen
2014-01-26 17:46       ` Lars-Peter Clausen

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=52E0FC22.8060903@metafoo.de \
    --to=lars@metafoo.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.