diff options
-rw-r--r-- | drivers/dma/xilinx/xilinx_vdma.c | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c index 70b2b32cba15..bc2ca457247e 100644 --- a/drivers/dma/xilinx/xilinx_vdma.c +++ b/drivers/dma/xilinx/xilinx_vdma.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
31 | #include <linux/iopoll.h> | ||
31 | #include <linux/module.h> | 32 | #include <linux/module.h> |
32 | #include <linux/of_address.h> | 33 | #include <linux/of_address.h> |
33 | #include <linux/of_dma.h> | 34 | #include <linux/of_dma.h> |
@@ -254,6 +255,9 @@ struct xilinx_vdma_device { | |||
254 | container_of(chan, struct xilinx_vdma_chan, common) | 255 | container_of(chan, struct xilinx_vdma_chan, common) |
255 | #define to_vdma_tx_descriptor(tx) \ | 256 | #define to_vdma_tx_descriptor(tx) \ |
256 | container_of(tx, struct xilinx_vdma_tx_descriptor, async_tx) | 257 | container_of(tx, struct xilinx_vdma_tx_descriptor, async_tx) |
258 | #define xilinx_vdma_poll_timeout(chan, reg, val, cond, delay_us, timeout_us) \ | ||
259 | readl_poll_timeout(chan->xdev->regs + chan->ctrl_offset + reg, val, \ | ||
260 | cond, delay_us, timeout_us) | ||
257 | 261 | ||
258 | /* IO accessors */ | 262 | /* IO accessors */ |
259 | static inline u32 vdma_read(struct xilinx_vdma_chan *chan, u32 reg) | 263 | static inline u32 vdma_read(struct xilinx_vdma_chan *chan, u32 reg) |
@@ -550,18 +554,17 @@ static bool xilinx_vdma_is_idle(struct xilinx_vdma_chan *chan) | |||
550 | */ | 554 | */ |
551 | static void xilinx_vdma_halt(struct xilinx_vdma_chan *chan) | 555 | static void xilinx_vdma_halt(struct xilinx_vdma_chan *chan) |
552 | { | 556 | { |
553 | int loop = XILINX_VDMA_LOOP_COUNT; | 557 | int err = 0; |
558 | u32 val; | ||
554 | 559 | ||
555 | vdma_ctrl_clr(chan, XILINX_VDMA_REG_DMACR, XILINX_VDMA_DMACR_RUNSTOP); | 560 | vdma_ctrl_clr(chan, XILINX_VDMA_REG_DMACR, XILINX_VDMA_DMACR_RUNSTOP); |
556 | 561 | ||
557 | /* Wait for the hardware to halt */ | 562 | /* Wait for the hardware to halt */ |
558 | do { | 563 | err = xilinx_vdma_poll_timeout(chan, XILINX_VDMA_REG_DMASR, val, |
559 | if (vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR) & | 564 | (val & XILINX_VDMA_DMASR_HALTED), 0, |
560 | XILINX_VDMA_DMASR_HALTED) | 565 | XILINX_VDMA_LOOP_COUNT); |
561 | break; | ||
562 | } while (loop--); | ||
563 | 566 | ||
564 | if (!loop) { | 567 | if (err) { |
565 | dev_err(chan->dev, "Cannot stop channel %p: %x\n", | 568 | dev_err(chan->dev, "Cannot stop channel %p: %x\n", |
566 | chan, vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR)); | 569 | chan, vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR)); |
567 | chan->err = true; | 570 | chan->err = true; |
@@ -576,18 +579,17 @@ static void xilinx_vdma_halt(struct xilinx_vdma_chan *chan) | |||
576 | */ | 579 | */ |
577 | static void xilinx_vdma_start(struct xilinx_vdma_chan *chan) | 580 | static void xilinx_vdma_start(struct xilinx_vdma_chan *chan) |
578 | { | 581 | { |
579 | int loop = XILINX_VDMA_LOOP_COUNT; | 582 | int err = 0; |
583 | u32 val; | ||
580 | 584 | ||
581 | vdma_ctrl_set(chan, XILINX_VDMA_REG_DMACR, XILINX_VDMA_DMACR_RUNSTOP); | 585 | vdma_ctrl_set(chan, XILINX_VDMA_REG_DMACR, XILINX_VDMA_DMACR_RUNSTOP); |
582 | 586 | ||
583 | /* Wait for the hardware to start */ | 587 | /* Wait for the hardware to start */ |
584 | do { | 588 | err = xilinx_vdma_poll_timeout(chan, XILINX_VDMA_REG_DMASR, val, |
585 | if (!(vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR) & | 589 | !(val & XILINX_VDMA_DMASR_HALTED), 0, |
586 | XILINX_VDMA_DMASR_HALTED)) | 590 | XILINX_VDMA_LOOP_COUNT); |
587 | break; | ||
588 | } while (loop--); | ||
589 | 591 | ||
590 | if (!loop) { | 592 | if (err) { |
591 | dev_err(chan->dev, "Cannot start channel %p: %x\n", | 593 | dev_err(chan->dev, "Cannot start channel %p: %x\n", |
592 | chan, vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR)); | 594 | chan, vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR)); |
593 | 595 | ||
@@ -754,21 +756,17 @@ static void xilinx_vdma_complete_descriptor(struct xilinx_vdma_chan *chan) | |||
754 | */ | 756 | */ |
755 | static int xilinx_vdma_reset(struct xilinx_vdma_chan *chan) | 757 | static int xilinx_vdma_reset(struct xilinx_vdma_chan *chan) |
756 | { | 758 | { |
757 | int loop = XILINX_VDMA_LOOP_COUNT; | 759 | int err = 0; |
758 | u32 tmp; | 760 | u32 tmp; |
759 | 761 | ||
760 | vdma_ctrl_set(chan, XILINX_VDMA_REG_DMACR, XILINX_VDMA_DMACR_RESET); | 762 | vdma_ctrl_set(chan, XILINX_VDMA_REG_DMACR, XILINX_VDMA_DMACR_RESET); |
761 | 763 | ||
762 | tmp = vdma_ctrl_read(chan, XILINX_VDMA_REG_DMACR) & | ||
763 | XILINX_VDMA_DMACR_RESET; | ||
764 | |||
765 | /* Wait for the hardware to finish reset */ | 764 | /* Wait for the hardware to finish reset */ |
766 | do { | 765 | err = xilinx_vdma_poll_timeout(chan, XILINX_VDMA_REG_DMACR, tmp, |
767 | tmp = vdma_ctrl_read(chan, XILINX_VDMA_REG_DMACR) & | 766 | !(tmp & XILINX_VDMA_DMACR_RESET), 0, |
768 | XILINX_VDMA_DMACR_RESET; | 767 | XILINX_VDMA_LOOP_COUNT); |
769 | } while (loop-- && tmp); | ||
770 | 768 | ||
771 | if (!loop) { | 769 | if (err) { |
772 | dev_err(chan->dev, "reset timeout, cr %x, sr %x\n", | 770 | dev_err(chan->dev, "reset timeout, cr %x, sr %x\n", |
773 | vdma_ctrl_read(chan, XILINX_VDMA_REG_DMACR), | 771 | vdma_ctrl_read(chan, XILINX_VDMA_REG_DMACR), |
774 | vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR)); | 772 | vdma_ctrl_read(chan, XILINX_VDMA_REG_DMASR)); |
@@ -777,7 +775,7 @@ static int xilinx_vdma_reset(struct xilinx_vdma_chan *chan) | |||
777 | 775 | ||
778 | chan->err = false; | 776 | chan->err = false; |
779 | 777 | ||
780 | return 0; | 778 | return err; |
781 | } | 779 | } |
782 | 780 | ||
783 | /** | 781 | /** |