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
WARNING: multiple messages have this Message-ID (diff)
From: Vinod Koul <vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
To: M'boumba Cedric Madianga
<cedric.madianga-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
pawel.moll-5wv7dgnIgG8@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org,
galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
dmaengine-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [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-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
WARNING: multiple messages have this Message-ID (diff)
From: Vinod Koul <vinod.koul@intel.com>
To: "M'boumba Cedric Madianga" <cedric.madianga@gmail.com>
Cc: mcoquelin.stm32@gmail.com, robh+dt@kernel.org,
pawel.moll@arm.com, mark.rutland@arm.com,
ijc+devicetree@hellion.org.uk, galak@codeaurora.org,
linux@arm.linux.org.uk, linux-arm-kernel@lists.infradead.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
dmaengine@vger.kernel.org
Subject: Re: [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
next prev parent reply other threads:[~2015-10-14 11:16 UTC|newest]
Thread overview: 51+ 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 ` 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-13 14:05 ` M'boumba Cedric Madianga
2015-10-14 8:54 ` 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:05 ` M'boumba Cedric Madianga
2015-10-13 14:34 ` Daniel Thompson
2015-10-13 14:34 ` Daniel Thompson
2015-10-13 14:34 ` Daniel Thompson
2015-10-14 7:54 ` M'boumba Cedric Madianga
2015-10-14 7:54 ` M'boumba Cedric Madianga
2015-10-14 7:54 ` M'boumba Cedric Madianga
2015-10-14 8:52 ` Daniel Thompson
2015-10-14 8:52 ` Daniel Thompson
2015-10-14 8:57 ` M'boumba Cedric Madianga
2015-10-14 8:57 ` M'boumba Cedric Madianga
2015-10-14 8:57 ` M'boumba Cedric Madianga
2015-10-14 13:17 ` M'boumba Cedric Madianga
2015-10-14 13:17 ` M'boumba Cedric Madianga
2015-10-14 13:29 ` Daniel Thompson
2015-10-14 13:29 ` Daniel Thompson
2015-10-14 13:29 ` Daniel Thompson
2015-10-14 13:41 ` M'boumba Cedric Madianga
2015-10-14 13:41 ` M'boumba Cedric Madianga
2015-10-14 14:24 ` Daniel Thompson
2015-10-14 14:24 ` Daniel Thompson
2015-10-14 15:26 ` M'boumba Cedric Madianga
2015-10-14 15:26 ` M'boumba Cedric Madianga
2015-10-14 15:26 ` M'boumba Cedric Madianga
2015-10-14 15:28 ` Daniel Thompson
2015-10-14 15:28 ` Daniel Thompson
2015-10-14 15:41 ` M'boumba Cedric Madianga
2015-10-14 15:41 ` M'boumba Cedric Madianga
2015-10-14 15:41 ` M'boumba Cedric Madianga
2015-10-15 4:07 ` Vinod Koul
2015-10-15 4:07 ` Vinod Koul
2015-10-15 4:07 ` Vinod Koul
2015-10-14 11:16 ` Vinod Koul [this message]
2015-10-14 11:16 ` Vinod Koul
2015-10-14 11:16 ` Vinod Koul
2015-10-14 13:07 ` M'boumba Cedric Madianga
2015-10-14 13:07 ` M'boumba Cedric Madianga
2015-10-14 14:14 ` Vinod Koul
2015-10-14 14:14 ` Vinod Koul
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 ` 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
2015-10-13 14:05 ` 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 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.