Message ID | 20100830234801.GA16862@july |
---|---|
State | New, archived |
Headers | show |
On Tue, 2010-08-31 at 08:48 +0900, Kyungmin Park wrote: > writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD); > > + timeout = jiffies + msec_to_jiffies(20); Are you completely absolutely 100% totally sure 20msecs is enough?
On Wed, Sep 1, 2010 at 8:02 AM, Artem Bityutskiy <dedekind1@gmail.com> wrote: > On Tue, 2010-08-31 at 08:48 +0900, Kyungmin Park wrote: >> writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD); >> >> + timeout = jiffies + msec_to_jiffies(20); > > Are you completely absolutely 100% totally sure 20msecs is enough? Actually there's no mention about the timeout time in the Spec. but I tested it both s5pc110 and s5pc210. and working well. No matter increase the time but I give the 4 chance to the DMA routine. since we got the 5msec times. and in case of s5pc110 it's implemented the HRT. so it's really enough. If the DMA takes more time than 20msec, it's really slow devices and can't use it. as you know the real transfer size is 2KiB or 4KiB. Thank you, Kyungmin Park > > -- > Best Regards, > Artem Bityutskiy (Битюцкий Артём) > >
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c index d604629..bdaa228 100644 --- a/drivers/mtd/onenand/samsung.c +++ b/drivers/mtd/onenand/samsung.c @@ -535,6 +535,7 @@ static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction) { void __iomem *base = onenand->dma_addr; int status; + unsigned long timeout; writel(src, base + S5PC110_DMA_SRC_ADDR); writel(dst, base + S5PC110_DMA_DST_ADDR); @@ -552,15 +553,17 @@ static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction) writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD); + timeout = jiffies + msec_to_jiffies(20); + do { status = readl(base + S5PC110_DMA_TRANS_STATUS); - } while (!(status & S5PC110_DMA_TRANS_STATUS_TD)); - - if (status & S5PC110_DMA_TRANS_STATUS_TE) { - writel(S5PC110_DMA_TRANS_CMD_TEC, base + S5PC110_DMA_TRANS_CMD); - writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD); - return -EIO; - } + if (status & S5PC110_DMA_TRANS_STATUS_TE) { + writel(S5PC110_DMA_TRANS_CMD_TEC, + base + S5PC110_DMA_TRANS_CMD); + return -EIO; + } + } while (!(status & S5PC110_DMA_TRANS_STATUS_TD) && + time_before(jiffies, timeout)); writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD);