linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: vinod.koul@intel.com (Vinod Koul)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 2/4] dmaengine: Add STM32 DMA driver
Date: Wed, 14 Oct 2015 16:46:15 +0530	[thread overview]
Message-ID: <20151014111615.GR27370@localhost> (raw)
In-Reply-To: <1444745127-1105-3-git-send-email-cedric.madianga@gmail.com>

On Tue, Oct 13, 2015 at 04:05:25PM +0200, M'boumba Cedric Madianga wrote:
> +#define STM32_DMA_LISR			0x0000 /* DMA Low Int Status Reg */
> +#define STM32_DMA_HISR			0x0004 /* DMA High Int Status Reg */
> +#define STM32_DMA_LIFCR			0x0008 /* DMA Low Int Flag Clear Reg */
> +#define STM32_DMA_HIFCR			0x000c /* DMA High Int Flag Clear Reg */
> +#define STM32_DMA_TCI			BIT(5) /* Transfer Complete Interrupt */
> +#define STM32_DMA_HTI			BIT(4) /* Half Transfer Interrupt */
> +#define STM32_DMA_TEI			BIT(3) /* Transfer Error Interrupt */
> +#define STM32_DMA_DMEI			BIT(2) /* Direct Mode Error Interrupt */
> +#define STM32_DMA_FEI			BIT(0) /* FIFO Error Interrupt */

Why not use BIT() for everything here and make it consistent

Also where ever possible stick to 80 char limit like above you can

> +
> +/* DMA Stream x Configuration Register */
> +#define STM32_DMA_SCR(x)		(0x0010 + 0x18 * (x)) /* x = 0..7 */
> +#define STM32_DMA_SCR_REQ(n)		((n & 0x7) << 25)

this and below looks ugly and hard to maintain, are you sure spec doesn't
have a formulae for these?

> +static inline uint32_t stm32_dma_read(struct stm32_dma_device *dmadev, u32 reg)

this and few other could be made more readable

> +static struct stm32_dma_desc *stm32_dma_alloc_desc(unsigned int num_sgs)
> +{
> +	return kzalloc(sizeof(struct stm32_dma_desc) +
> +		       sizeof(struct stm32_dma_sg_req) * num_sgs, GFP_ATOMIC);

Not GFP_NOWAIT ?

> +static enum stm32_dma_width stm32_get_dma_width(struct stm32_dma_chan *chan,
> +						enum dma_slave_buswidth width)
> +{
> +	switch (width) {
> +	case DMA_SLAVE_BUSWIDTH_1_BYTE:
> +		return STM32_DMA_BYTE;
> +	case DMA_SLAVE_BUSWIDTH_2_BYTES:
> +		return STM32_DMA_HALF_WORD;
> +	case DMA_SLAVE_BUSWIDTH_4_BYTES:
> +		return STM32_DMA_WORD;
> +	default:
> +		dev_warn(chan2dev(chan),
> +			 "Dma bus width not supported, using 32bits\n");
> +		return STM32_DMA_WORD;

pls return error here
Assuming wrong parameter can cause havoc of transfer, so is not advisable

> +static enum stm32_dma_burst_size stm32_get_dma_burst(
> +		struct stm32_dma_chan *chan, u32 maxburst)
> +{
> +	switch (maxburst) {
> +	case 0:
> +	case 1:
> +		return STM32_DMA_BURST_SINGLE;
> +	case 4:
> +		return STM32_DMA_BURST_INCR4;
> +	case 8:
> +		return STM32_DMA_BURST_INCR8;
> +	case 16:
> +		return STM32_DMA_BURST_INCR16;
> +	default:
> +		dev_warn(chan2dev(chan),
> +			 "Dma burst size not supported, using single\n");
> +		return STM32_DMA_BURST_SINGLE;

here too

> +	}
> +}
> +
> +static int stm32_dma_slave_config(struct dma_chan *c,
> +				  struct dma_slave_config *config)
> +{
> +	struct stm32_dma_chan *chan = to_stm32_dma_chan(c);
> +
> +	if (chan->busy) {
> +		dev_err(chan2dev(chan), "Configuration not allowed\n");
> +		return -EBUSY;
> +	}

That is false condition. This configuration should be used for next
descriptor prepare

> +static int stm32_dma_disable_chan(struct stm32_dma_chan *chan)
> +{
> +	struct stm32_dma_device *dmadev = stm32_dma_chan_get_dev(chan);
> +	unsigned long timeout = jiffies + msecs_to_jiffies(5000);
> +	u32 dma_scr;
> +
> +	dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id));
> +	if (dma_scr & STM32_DMA_SCR_EN) {
> +		dma_scr &= ~STM32_DMA_SCR_EN;
> +		stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), dma_scr);
> +
> +		do {
> +			dma_scr = stm32_dma_read(dmadev,
> +						 STM32_DMA_SCR(chan->id));
> +			dma_scr &= STM32_DMA_SCR_EN;
> +			if (!dma_scr)
> +				break;

empty line here would improve readability

> +static irqreturn_t stm32_dma_chan_irq(int irq, void *devid)
> +{
> +	struct stm32_dma_chan *chan = devid;
> +	struct stm32_dma_device *dmadev = stm32_dma_chan_get_dev(chan);
> +	u32 status, scr, sfcr;
> +
> +	spin_lock(&chan->vchan.lock);
> +
> +	status = stm32_dma_irq_status(chan);
> +	scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id));
> +	sfcr = stm32_dma_read(dmadev, STM32_DMA_SFCR(chan->id));
> +
> +	if ((status & STM32_DMA_HTI) && (scr & STM32_DMA_SCR_HTIE)) {
> +		stm32_dma_irq_clear(chan, STM32_DMA_HTI);
> +		vchan_cyclic_callback(&chan->desc->vdesc);
> +		spin_unlock(&chan->vchan.lock);
> +		return IRQ_HANDLED;

line here please and below

> +	} else if ((status & STM32_DMA_TCI) && (scr & STM32_DMA_SCR_TCIE)) {
> +		stm32_dma_irq_clear(chan, STM32_DMA_TCI);
> +		stm32_dma_handle_chan_done(chan);
> +		spin_unlock(&chan->vchan.lock);
> +		return IRQ_HANDLED;
> +	} else if ((status & STM32_DMA_TEI) && (scr & STM32_DMA_SCR_TEIE)) {
> +		dev_err(chan2dev(chan), "DMA error: received TEI event\n");
> +		stm32_dma_irq_clear(chan, STM32_DMA_TEI);
> +		chan->status = DMA_ERROR;
> +		spin_unlock(&chan->vchan.lock);
> +		return IRQ_HANDLED;
> +	} else if ((status & STM32_DMA_FEI) && (sfcr & STM32_DMA_SFCR_FEIE)) {
> +		dev_err(chan2dev(chan), "DMA error: received FEI event\n");
> +		stm32_dma_irq_clear(chan, STM32_DMA_FEI);
> +		chan->status = DMA_ERROR;
> +		spin_unlock(&chan->vchan.lock);
> +		return IRQ_HANDLED;

this is repeat of above apart from err print!!

> +	} else if ((status & STM32_DMA_DMEI) && (scr & STM32_DMA_SCR_DMEIE)) {
> +		dev_err(chan2dev(chan), "DMA error: received DMEI event\n");
> +		stm32_dma_irq_clear(chan, STM32_DMA_DMEI);
> +		chan->status = DMA_ERROR;
> +		spin_unlock(&chan->vchan.lock);
> +		return IRQ_HANDLED;

same here :(

> +static enum dma_status stm32_dma_tx_status(struct dma_chan *c,
> +					   dma_cookie_t cookie,
> +					   struct dma_tx_state *state)
> +{
> +	struct stm32_dma_chan *chan = to_stm32_dma_chan(c);
> +	struct virt_dma_desc *vdesc;
> +	enum dma_status status;
> +	unsigned long flags;
> +	unsigned int residue;
> +
> +	status = dma_cookie_status(c, cookie, state);
> +	if (status == DMA_COMPLETE)
> +		return status;
> +
> +	if (!state)
> +		return chan->status;
why channel status and not status from dma_cookie_status()?

> +static int stm32_dma_remove(struct platform_device *pdev)
> +{
> +	struct stm32_dma_device *dmadev = platform_get_drvdata(pdev);
> +
> +	of_dma_controller_free(pdev->dev.of_node);
> +
> +	dma_async_device_unregister(&dmadev->ddev);
> +
> +	clk_disable_unprepare(dmadev->clk);

and your irq is enabled and you can still receive interrupts and schedule
tasklets :(

-- 
~Vinod

  parent reply	other threads:[~2015-10-14 11:16 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-13 14:05 [PATCH v2 0/4] Add support for STM32 DMA M'boumba Cedric Madianga
2015-10-13 14:05 ` [PATCH v2 1/4] dt-bindings: Document the STM32 DMA bindings M'boumba Cedric Madianga
2015-10-14  8:54   ` M'boumba Cedric Madianga
2015-10-13 14:05 ` [PATCH v2 2/4] dmaengine: Add STM32 DMA driver M'boumba Cedric Madianga
2015-10-13 14:34   ` Daniel Thompson
2015-10-14  7:54     ` M'boumba Cedric Madianga
2015-10-14  8:52       ` Daniel Thompson
2015-10-14  8:57         ` M'boumba Cedric Madianga
2015-10-14 13:17       ` M'boumba Cedric Madianga
2015-10-14 13:29         ` Daniel Thompson
2015-10-14 13:41           ` M'boumba Cedric Madianga
2015-10-14 14:24             ` Daniel Thompson
2015-10-14 15:26               ` M'boumba Cedric Madianga
2015-10-14 15:28                 ` Daniel Thompson
2015-10-14 15:41                   ` M'boumba Cedric Madianga
2015-10-15  4:07                     ` Vinod Koul
2015-10-14 11:16   ` Vinod Koul [this message]
2015-10-14 13:07     ` M'boumba Cedric Madianga
2015-10-14 14:14       ` Vinod Koul
2015-10-13 14:05 ` [PATCH v2 3/4] ARM: dts: Add STM32 DMA support for STM32F429 MCU M'boumba Cedric Madianga
2015-10-13 14:05 ` [PATCH v2 4/4] ARM: configs: Add STM32 DMA support in STM32 defconfig M'boumba Cedric Madianga

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=20151014111615.GR27370@localhost \
    --to=vinod.koul@intel.com \
    --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 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).