* [PATCH] MTD: OneNAND: S5PC110: Implement DMA interrupt method
@ 2010-09-27 10:01 Kyungmin Park
2010-09-28 6:28 ` Artem Bityutskiy
0 siblings, 1 reply; 3+ messages in thread
From: Kyungmin Park @ 2010-09-27 10:01 UTC (permalink / raw)
To: linux-mtd; +Cc: Artem.Bityutskiy, dwmw2
From: Kyungmin Park <kyungmin.park@samsung.com>
Implement DMA interrupt method. previous time it polls the DMA status.
It can reduce the CPU power but decrease the performance a little.
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/mtd/onenand/samsung.c | 85 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 84 insertions(+), 1 deletions(-)
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
index afdb4c5..214ed1e 100644
--- a/drivers/mtd/onenand/samsung.c
+++ b/drivers/mtd/onenand/samsung.c
@@ -22,6 +22,7 @@
#include <linux/mtd/onenand.h>
#include <linux/mtd/partitions.h>
#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
#include <asm/mach/flash.h>
#include <plat/regs-onenand.h>
@@ -81,6 +82,17 @@ enum soc_type {
#define S5PC110_DMA_TRANS_CMD 0x418
#define S5PC110_DMA_TRANS_STATUS 0x41C
#define S5PC110_DMA_TRANS_DIR 0x420
+#define S5PC110_INTC_DMA_CLR 0x1004
+#define S5PC110_INTC_ONENAND_CLR 0x1008
+#define S5PC110_INTC_DMA_MASK 0x1024
+#define S5PC110_INTC_ONENAND_MASK 0x1028
+#define S5PC110_INTC_DMA_PEND 0x1044
+#define S5PC110_INTC_ONENAND_PEND 0x1048
+#define S5PC110_INTC_DMA_STATUS 0x1064
+#define S5PC110_INTC_ONENAND_STATUS 0x1068
+
+#define S5PC110_INTC_DMA_TD (1 << 24)
+#define S5PC110_INTC_DMA_TE (1 << 16)
#define S5PC110_DMA_CFG_SINGLE (0x0 << 16)
#define S5PC110_DMA_CFG_4BURST (0x2 << 16)
@@ -134,6 +146,7 @@ struct s3c_onenand {
void __iomem *dma_addr;
struct resource *dma_res;
unsigned long phys_base;
+ struct completion complete;
#ifdef CONFIG_MTD_PARTITIONS
struct mtd_partition *parts;
#endif
@@ -531,7 +544,9 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
return 0;
}
-static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction)
+static int (*s5pc110_dma_ops)(void *dst, void *src, size_t count, int direction);
+
+static int s5pc110_dma_poll(void *dst, void *src, size_t count, int direction)
{
void __iomem *base = onenand->dma_addr;
int status;
@@ -575,6 +590,60 @@ static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction)
return 0;
}
+static irqreturn_t s5pc110_onenand_irq(int irq, void *data)
+{
+ void __iomem *base = onenand->dma_addr;
+ int status, cmd = 0;
+
+ status = readl(base + S5PC110_INTC_DMA_STATUS);
+
+ if (likely(status & S5PC110_INTC_DMA_TD))
+ cmd = S5PC110_DMA_TRANS_CMD_TDC;
+
+ if (unlikely(status & S5PC110_INTC_DMA_TE))
+ cmd = S5PC110_DMA_TRANS_CMD_TEC;
+
+ writel(cmd, base + S5PC110_DMA_TRANS_CMD);
+ writel(status, base + S5PC110_INTC_DMA_CLR);
+
+ if (!onenand->complete.done)
+ complete(&onenand->complete);
+
+ return IRQ_HANDLED;
+}
+
+static int s5pc110_dma_irq(void *dst, void *src, size_t count, int direction)
+{
+ void __iomem *base = onenand->dma_addr;
+ int status;
+
+ status = readl(base + S5PC110_INTC_DMA_MASK);
+ if (status) {
+ status &= ~(S5PC110_INTC_DMA_TD | S5PC110_INTC_DMA_TE);
+ writel(status, base + S5PC110_INTC_DMA_MASK);
+ }
+
+ writel(src, base + S5PC110_DMA_SRC_ADDR);
+ writel(dst, base + S5PC110_DMA_DST_ADDR);
+
+ if (direction == S5PC110_DMA_DIR_READ) {
+ writel(S5PC110_DMA_SRC_CFG_READ, base + S5PC110_DMA_SRC_CFG);
+ writel(S5PC110_DMA_DST_CFG_READ, base + S5PC110_DMA_DST_CFG);
+ } else {
+ writel(S5PC110_DMA_SRC_CFG_WRITE, base + S5PC110_DMA_SRC_CFG);
+ writel(S5PC110_DMA_DST_CFG_WRITE, base + S5PC110_DMA_DST_CFG);
+ }
+
+ writel(count, base + S5PC110_DMA_TRANS_SIZE);
+ writel(direction, base + S5PC110_DMA_TRANS_DIR);
+
+ writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD);
+
+ wait_for_completion_timeout(&onenand->complete, msecs_to_jiffies(20));
+
+ return 0;
+}
+
static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
unsigned char *buffer, int offset, size_t count)
{
@@ -919,6 +988,20 @@ static int s3c_onenand_probe(struct platform_device *pdev)
}
onenand->phys_base = onenand->base_res->start;
+
+ s5pc110_dma_ops = s5pc110_dma_poll;
+ /* Interrupt support */
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (r) {
+ init_completion(&onenand->complete);
+ s5pc110_dma_ops = s5pc110_dma_irq;
+ err = request_irq(r->start, s5pc110_onenand_irq,
+ IRQF_SHARED, "onenand", &onenand);
+ if (err) {
+ dev_err(&pdev->dev, "failed to get irq\n");
+ goto scan_failed;
+ }
+ }
}
if (onenand_scan(mtd, 1)) {
--
1.5.3.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] MTD: OneNAND: S5PC110: Implement DMA interrupt method
2010-09-27 10:01 [PATCH] MTD: OneNAND: S5PC110: Implement DMA interrupt method Kyungmin Park
@ 2010-09-28 6:28 ` Artem Bityutskiy
2010-09-28 7:29 ` Kyungmin Park
0 siblings, 1 reply; 3+ messages in thread
From: Artem Bityutskiy @ 2010-09-28 6:28 UTC (permalink / raw)
To: Kyungmin Park; +Cc: dwmw2, linux-mtd
On Mon, 2010-09-27 at 19:01 +0900, Kyungmin Park wrote:
> From: Kyungmin Park <kyungmin.park@samsung.com>
>
> Implement DMA interrupt method. previous time it polls the DMA status.
> It can reduce the CPU power but decrease the performance a little.
>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Does not apply to the l2 tree. Also it is not clear at all whether it
depends on the previous series or it is completely independent. Please,
re-send with the other patches which I did not take yet.
--
Best Regards,
Artem Bityutskiy (Артём Битюцкий)
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] MTD: OneNAND: S5PC110: Implement DMA interrupt method
2010-09-28 6:28 ` Artem Bityutskiy
@ 2010-09-28 7:29 ` Kyungmin Park
0 siblings, 0 replies; 3+ messages in thread
From: Kyungmin Park @ 2010-09-28 7:29 UTC (permalink / raw)
To: Artem.Bityutskiy; +Cc: dwmw2, linux-mtd
On Tue, Sep 28, 2010 at 3:28 PM, Artem Bityutskiy
<Artem.Bityutskiy@nokia.com> wrote:
> On Mon, 2010-09-27 at 19:01 +0900, Kyungmin Park wrote:
>> From: Kyungmin Park <kyungmin.park@samsung.com>
>>
>> Implement DMA interrupt method. previous time it polls the DMA status.
>> It can reduce the CPU power but decrease the performance a little.
>>
>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>
> Does not apply to the l2 tree. Also it is not clear at all whether it
> depends on the previous series or it is completely independent. Please,
> re-send with the other patches which I did not take yet.
It's dependent on previous patches, I think these patches including
previous are for 2.6.37.
Okay I'll re-send based on l2 tree.
Thank you,
Kyungmin Park
>
> --
> Best Regards,
> Artem Bityutskiy (Артём Битюцкий)
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-09-28 7:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-27 10:01 [PATCH] MTD: OneNAND: S5PC110: Implement DMA interrupt method Kyungmin Park
2010-09-28 6:28 ` Artem Bityutskiy
2010-09-28 7:29 ` Kyungmin Park
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).