Skip to contentSkip to conversation

sh: override DMA interrupt handler to dma-sh driver

RFC PATCH New Nobuhiro Iwamatsu 1 participant 1 message Sep 29, 2008 SuperH

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 sh: override DMA interrupt handler to dma-sh driver

Dma-sh has fixed interrupt handler and cannot register an interrupt for exclusive use of the device with dma.

I added a handler to sh_dmac_request_dma and reviced it to be able to appoint a handler.

---
 arch/sh/drivers/dma/Kconfig       |    2 +-
 arch/sh/drivers/dma/dma-api.c     |   63 +++++++++++++++++++++++++-----------
 arch/sh/drivers/dma/dma-pvr2.c    |    2 +-
 arch/sh/drivers/dma/dma-sh.c      |   38 ++++++++++++----------
 arch/sh/drivers/dma/dma-sh.h      |   46 +++++++++++++++++++--------
 arch/sh/drivers/dma/dmabrg.c      |    2 +-
 arch/sh/include/asm/dma.h         |   36 +++++++++++++++++---
 arch/sh/include/cpu-sh4/cpu/dma.h |    9 +++++-
 8 files changed, 137 insertions(+), 61 deletions(-)
arch/sh/drivers/dma/Kconfig +1 -1
index 0193636..0c4ee21 100644
@@ -12,7 +12,7 @@ config SH_DMA
 config NR_ONCHIP_DMA_CHANNELS
 	int
 	depends on SH_DMA
-	default "6" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721
+	default "6" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721 || CPU_SUBTYPE_SH7763
 	default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R
 	default "12" if CPU_SUBTYPE_SH7780
 	default "4"
arch/sh/drivers/dma/dma-api.c +44 -19

128 lines not on this page · raw message

arch/sh/drivers/dma/dma-pvr2.c +1 -1
index 391cbe1..2016e88 100644
@@ -89,7 +89,7 @@ static struct dma_info pvr2_dma_info = {
 static int __init pvr2_dma_init(void)
 {
 	setup_irq(HW_EVENT_PVR2_DMA, &pvr2_dma_irq);
-	request_dma(PVR2_CASCADE_CHAN, "pvr2 cascade");
+	request_dma(PVR2_CASCADE_CHAN, "pvr2 cascade",NULL, NULL);
 
 	return register_dmac(&pvr2_dma_info);
 }
arch/sh/drivers/dma/dma-sh.c +20 -18
index b2ffe64..69cb807 100644
@@ -28,6 +28,7 @@ static int dmte_irq_map[] = {
     defined(CONFIG_CPU_SUBTYPE_SH7721)  ||	\
     defined(CONFIG_CPU_SUBTYPE_SH7751R) ||	\
     defined(CONFIG_CPU_SUBTYPE_SH7760)  ||	\
+    defined(CONFIG_CPU_SUBTYPE_SH7763)  ||	\
     defined(CONFIG_CPU_SUBTYPE_SH7709)  ||	\
     defined(CONFIG_CPU_SUBTYPE_SH7780)
 	DMTE4_IRQ,
@@ -88,18 +89,25 @@ static irqreturn_t dma_tei(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int sh_dmac_request_dma(struct dma_channel *chan)
+static int sh_dmac_request_dma(struct dma_channel *chan, irq_handler_t handler, void *data)
 {
 	if (unlikely(!(chan->flags & DMA_TEI_CAPABLE)))
 		return 0;
 
+	if (handler)
+		return request_irq(get_dmte_irq(chan->chan), handler,
+			IRQF_DISABLED, chan->dev_id, data);
+
 	return request_irq(get_dmte_irq(chan->chan), dma_tei,
-			   IRQF_DISABLED, chan->dev_id, chan);
+			IRQF_DISABLED, chan->dev_id, chan);
 }
 
-static void sh_dmac_free_dma(struct dma_channel *chan)
+static void sh_dmac_free_dma(struct dma_channel *chan, void *data)
 {
-	free_irq(get_dmte_irq(chan->chan), chan);
+	if (data)
+		free_irq(get_dmte_irq(chan->chan), data);
+	else
+		free_irq(get_dmte_irq(chan->chan), chan);
 }
 
 static int
@@ -116,17 +124,14 @@ sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
 	}
 
 	ctrl_outl(chcr, CHCR[chan->chan]);
-
 	chan->flags |= DMA_CONFIGURED;
 	return 0;
 }
 
 static void sh_dmac_enable_dma(struct dma_channel *chan)
 {
-	int irq;
-	u32 chcr;
+	u32 chcr= ctrl_inl(CHCR[chan->chan]);
 
-	chcr = ctrl_inl(CHCR[chan->chan]);
 	chcr |= CHCR_DE;
 
 	if (chan->flags & DMA_TEI_CAPABLE)
@@ -134,21 +139,15 @@ static void sh_dmac_enable_dma(struct dma_channel *chan)
 
 	ctrl_outl(chcr, CHCR[chan->chan]);
 
-	if (chan->flags & DMA_TEI_CAPABLE) {
-		irq = get_dmte_irq(chan->chan);
-		enable_irq(irq);
-	}
+	if (chan->flags & DMA_TEI_CAPABLE)
+		enable_irq(get_dmte_irq(chan->chan));
 }
 
 static void sh_dmac_disable_dma(struct dma_channel *chan)
 {
-	int irq;
 	u32 chcr;
-
-	if (chan->flags & DMA_TEI_CAPABLE) {
-		irq = get_dmte_irq(chan->chan);
-		disable_irq(irq);
-	}
+	if (chan->flags & DMA_TEI_CAPABLE)
+		disable_irq(get_dmte_irq(chan->chan));
 
 	chcr = ctrl_inl(CHCR[chan->chan]);
 	chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE);
@@ -205,6 +204,7 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan)
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
     defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7763) || \
     defined(CONFIG_CPU_SUBTYPE_SH7780)
 #define dmaor_read_reg()	ctrl_inw(DMAOR)
 #define dmaor_write_reg(data)	ctrl_outw(data, DMAOR)
@@ -249,6 +249,8 @@ static struct dma_ops sh_dmac_ops = {
 	.get_residue	= sh_dmac_get_dma_residue,
 	.xfer		= sh_dmac_xfer_dma,
 	.configure	= sh_dmac_configure_channel,
+	.start = sh_dmac_enable_dma,
+	.stop = sh_dmac_disable_dma,
 };
 
 static struct dma_info sh_dmac_info = {
arch/sh/drivers/dma/dma-sh.h +32 -14

69 lines not on this page · raw message

arch/sh/drivers/dma/dmabrg.c +1 -1
index 5e22689..38c3edc 100644
@@ -160,7 +160,7 @@ static int __init dmabrg_init(void)
 
 #ifdef CONFIG_SH_DMA
 	/* request DMAC channel 0 before anyone else can get it */
-	ret = request_dma(0, "DMAC 0 (DMABRG)");
+	ret = request_dma(0, "DMAC 0 (DMABRG)", NULL, NULL);
 	if (ret < 0)
 		printk(KERN_INFO "DMABRG: DMAC ch0 not reserved!\n");
 #endif
arch/sh/include/asm/dma.h +30 -6
index beca712..e29fbd2 100644
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/dma.h
+ * arch/sh/include/asm/dma.h
  *
  * Copyright (C) 2003, 2004  Paul Mundt
  *
@@ -13,6 +13,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/wait.h>
+#include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/sysdev.h>
 #include <cpu/dma.h>
@@ -67,13 +68,16 @@ extern spinlock_t dma_spin_lock;
 struct dma_channel;
 
 struct dma_ops {
-	int (*request)(struct dma_channel *chan);
-	void (*free)(struct dma_channel *chan);
+	int (*request)(struct dma_channel *chan, irq_handler_t handler,
+						void *data);
+	void (*free)(struct dma_channel *chan, void *data);
 
 	int (*get_residue)(struct dma_channel *chan);
 	int (*xfer)(struct dma_channel *chan);
 	int (*configure)(struct dma_channel *chan, unsigned long flags);
 	int (*extend)(struct dma_channel *chan, unsigned long op, void *param);
+	void (*start)(struct dma_channel *chan);
+	void (*stop)(struct dma_channel *chan);
 };
 
 struct dma_channel {
@@ -124,6 +128,21 @@ struct dma_chan_caps {
 /* arch/sh/drivers/dma/dma-api.c */
 extern int dma_xfer(unsigned int chan, unsigned long from,
 		    unsigned long to, size_t size, unsigned int mode);
+/* SAR */
+#define dma_set_sar(val, chan)	ctrl_outl(val, SAR[chan])
+#define dma_get_sar(chan)		ctrl_inl(SAR[chan])
+/* DAR */
+#define dma_set_dar(val, chan)	ctrl_outl(val, DAR[chan])
+#define dma_get_dar(chan)		ctrl_inl(DAR[chan])
+/* DMATCR */
+#define dma_set_dmatcr(val, chan) ctrl_outl(val, DMATCR[chan])
+#define dma_get_dmatcr(chan) ctrl_inl(DMATCR[chan])
+/* CHCR */
+#define dma_set_chcr(val, chan)	ctrl_outl(val, CHCR[chan])
+#define dma_get_chcr(chan)		ctrl_inl(CHCR[chan])
+/* DMASR */
+#define dma_set_dmasr(val, chan)	ctrl_outw(val, DMASR[chan])
+#define dma_get_dmasr(chan)			ctrl_inw(DMASR[chan])
 
 #define dma_write(chan, from, to, size)	\
 	dma_xfer(chan, from, to, size, DMA_MODE_WRITE)
@@ -135,10 +154,15 @@ extern int dma_xfer(unsigned int chan, unsigned long from,
 #define dma_read_page(chan, from, to)	\
 	dma_read(chan, from, to, PAGE_SIZE)
 
+extern int dma_start(unsigned int chan);
+extern int dma_stop(unsigned int chan);
+
 extern int request_dma_bycap(const char **dmac, const char **caps,
-			     const char *dev_id);
-extern int request_dma(unsigned int chan, const char *dev_id);
-extern void free_dma(unsigned int chan);
+			const char *dev_id, irq_handler_t handler, void *data);
+extern int dmac_search_free_channel(void);
+extern int request_dma(unsigned int chan, const char *dev_id,
+			irq_handler_t handler, void *data);
+extern void free_dma(unsigned int chan, void *data);
 extern int get_dma_residue(unsigned int chan);
 extern struct dma_info *get_dma_info(unsigned int chan);
 extern struct dma_channel *get_dma_channel(unsigned int chan);
arch/sh/include/cpu-sh4/cpu/dma.h +8 -1
index 235b7cd..1d2bd3b 100644
@@ -15,7 +15,14 @@
 #define DMAE_IRQ	38
 
 #ifdef CONFIG_CPU_SH4A
-#define SH_DMAC_BASE	0xfc808020
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7763) ||\
+	defined(CONFIG_CPU_SUBTYPE_SH7764)
+# define SH_DMAC_BASE  0xff608020
+#else
+/* SH7780/SH7785 */
+# define SH_DMAC_BASE  0xfc808020
+#endif
 
 #define CHCR_TS_MASK	0x18
 #define CHCR_TS_SHIFT	3
Signature · 1 line
1.5.6.3