[PATCH] Topcliff DMA: Add the DMA driver [1/4]

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Masayuki Ohtake
Date: Tuesday, April 27, 2010 - 4:01 am

From: "Masayuki Ohtake" <masa-korg@dsn.okisemi.com>
To: "LKML" <linux-kernel@vger.kernel.org>
Cc: "Wang, Yong Y" <yong.y.wang@intel.com>,
	"Wang, Qi" <qi.wang@intel.com>,
	"Intel OTC" <joel.clark@intel.com>,
	"Andrew" <andrew.chih.howe.khor@intel.com>
Subject: [PATCH] Topcliff DMA: Add the DMA driver
Date: Tue, 27 Apr 2010 20:01:44 +0900
MIME-Version: 1.0
Content-Type: text/plain;
	charset="iso-2022-jp"
Content-Transfer-Encoding: 7bit
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2800.1983
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1983

From: Masayuki Ohtake <masa-korg@dsn.okisemi.com>

This driver implements DMA controls for Topcliff.

Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>

---
 drivers/dma/Kconfig   |
 drivers/dma/Makefile   |
 drivers/dma/pch_dma/Makefile  |
 drivers/dma/pch_dma/pch_common.h |
 drivers/dma/pch_dma/pch_debug.h |
 drivers/dma/pch_dma/pch_dma_hal.c |
 drivers/dma/pch_dma/pch_dma_hal.h |
 drivers/dma/pch_dma/pch_dma_main.c |
 drivers/dma/pch_dma/pch_dma_main.h |
 drivers/dma/pch_dma/pch_dma_pci.c |
 drivers/dma/pch_dma/pch_dma_pci.h |
+++++++++++++++++++++++++++++++ 11 files changed, zz insertions(+)
diff -urN linux-2.6.33.1/drivers/dma/Kconfig
topcliff-2.6.33.1/drivers/dma/Kconfig
--- linux-2.6.33.1/drivers/dma/Kconfig 2010-03-16 01:09:39.000000000 +0900
+++ topcliff-2.6.33.1/drivers/dma/Kconfig 2010-03-23 10:40:05.000000000
+0900
@@ -20,6 +20,14 @@
 config ASYNC_TX_DISABLE_CHANNEL_SWITCH
  bool

+config PCH_UART_DMA
+ tristate "PCH DMA Controller"
+ depends on PCI && SERIAL_8250_PCH_DMA
+ default y
+ help
+   This value must equal to SERIAL_8250_PCH. This config PCH_UART_DMA is
+   referred by PCH UART.
+
 config INTEL_IOATDMA
  tristate "Intel I/OAT DMA support"
  depends on PCI && X86
diff -urN linux-2.6.33.1/drivers/dma/Makefile
topcliff-2.6.33.1/drivers/dma/Makefile
--- linux-2.6.33.1/drivers/dma/Makefile 2010-03-16 01:09:39.000000000 +0900
+++ topcliff-2.6.33.1/drivers/dma/Makefile 2010-03-23 10:40:05.000000000
+0900
@@ -12,3 +12,4 @@
 obj-$(CONFIG_SH_DMAE) += shdma.o
 obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
 obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/
+obj-$(CONFIG_PCH_UART_DMA) += pch_dma/
diff -urN linux-2.6.33.1/drivers/dma/pch_dma/Makefile
topcliff-2.6.33.1/drivers/dma/pch_dma/Makefile
--- linux-2.6.33.1/drivers/dma/pch_dma/Makefile 1970-01-01
09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/dma/pch_dma/Makefile 2010-03-23
10:40:05.000000000 +0900
@@ -0,0 +1,5 @@
+#enable for debug;this can be added in Kconfig
+#EXTRA_CFLAGS += -DDEBUG
+
+obj-$(CONFIG_PCH_UART_DMA) += pch_dma.o
+pch_dma-objs := pch_dma_pci.o pch_dma_hal.o pch_dma_main.o
diff -urN linux-2.6.33.1/drivers/dma/pch_dma/pch_common.h
topcliff-2.6.33.1/drivers/dma/pch_dma/pch_common.h
--- linux-2.6.33.1/drivers/dma/pch_dma/pch_common.h 1970-01-01
09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/dma/pch_dma/pch_common.h 2010-04-27
11:46:20.000000000 +0900
@@ -0,0 +1,144 @@
+/*!
+ * @file pch_common.h
+ * @brief Provides the macro definitions used by all files.
+ * @version 1.0.0.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307,
USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ *
+ *
+ * created:
+ * OKISEMI 04/14/2010
+ *
+ */
+
+#ifndef __PCH_COMMON_H__
+#define __PCH_COMMON_H__
+
+/*! @ingroup Global
+@def      PCH_WRITE8
+@brief   Macro for writing 8 bit data to an io/mem address
+*/
+#define PCH_WRITE8(val, addr)   iowrite8((val), (void __iomem *)(addr))
+/*! @ingroup Global
+@def      PCH_LOG
+@brief   Macro for writing 16 bit data to an io/mem address
+*/
+#define PCH_WRITE16(val, addr)  iowrite16((val), (void __iomem *)(addr))
+/*! @ingroup Global
+@def      PCH_LOG
+@brief   Macro for writing 32 bit data to an io/mem address
+*/
+#define PCH_WRITE32(val, addr)  iowrite32((val), (void __iomem *)(addr))
+
+/*! @ingroup Global
+@def      PCH_READ8
+@brief   Macro for reading 8 bit data from an io/mem address
+*/
+#define PCH_READ8(addr)   ioread8((void __iomem *)(addr))
+/*! @ingroup Global
+@def      PCH_READ16
+@brief   Macro for reading 16 bit data from an io/mem address
+*/
+#define PCH_READ16(addr)  ioread16((void __iomem *)(addr))
+/*! @ingroup Global
+@def      PCH_READ32
+@brief   Macro for reading 32 bit data from an io/mem address
+*/
+#define PCH_READ32(addr)  ioread32((void __iomem *)(addr))
+/*! @ingroup Global
+@def      PCH_WRITE32_F
+@brief   Macro for writing 32 bit data to an io/mem address
+*/
+#define PCH_WRITE32_F(val, addr) do \
+ { PCH_WRITE32((val), (addr)); (void)PCH_READ32((addr)); } while (0);
+
+/*! @ingroup Global
+@def      PCH_WRITE_BYTE
+@brief   Macro for writing 1 byte data to an io/mem address
+*/
+#define PCH_WRITE_BYTE PCH_WRITE8
+/*! @ingroup Global
+@def      PCH_WRITE_WORD
+@brief   Macro for writing 1 word data to an io/mem address
+*/
+#define PCH_WRITE_WORD PCH_WRITE16
+/*! @ingroup Global
+@def      PCH_WRITE_LONG
+@brief   Macro for writing long data to an io/mem address
+*/
+#define PCH_WRITE_LONG PCH_WRITE32
+
+/*! @ingroup Global
+@def      PCH_READ_BYTE
+@brief   Macro for reading 1 byte data from an io/mem address
+*/
+#define PCH_READ_BYTE  PCH_READ8
+/*! @ingroup Global
+@def      PCH_READ_WORD
+@brief   Macro for reading 1 word data from an io/mem address
+*/
+#define PCH_READ_WORD  PCH_READ16
+/*! @ingroup Global
+@def      PCH_READ_LONG
+@brief   Macro for reading long data from an io/mem address
+*/
+#define PCH_READ_LONG  PCH_READ32
+
+/* Bit Manipulation Macros */
+
+/*! @ingroup Global
+@def      PCH_READ_LONG
+@brief   macro to set a specified bit(mask) at the
+   specified address
+*/
+#define PCH_SET_ADDR_BIT(addr, bitmask) PCH_WRITE_LONG((PCH_READ_LONG(addr)
|\
+        (bitmask)), (addr))
+
+/*! @ingroup Global
+@def     PCH_READ_LONG
+@brief  macro to clear a specified bit(mask) at the specified address
+*/
+#define PCH_CLR_ADDR_BIT(addr, bitmask) PCH_WRITE_LONG((PCH_READ_LONG(addr)
&\
+        ~(bitmask)), (addr))
+
+/*! @ingroup Global
+@def      PCH_READ_LONG
+@brief   macro to set a specified bitmask for a variable
+*/
+#define PCH_SET_BITMSK(var, bitmask) ((var) |= (bitmask))
+
+/*! @ingroup Global
+@def      PCH_READ_LONG
+@brief   macro to clear a specified bitmask for a variable
+*/
+#define PCH_CLR_BITMSK(var, bitmask) ((var) &= (~(bitmask)))
+
+/*! @ingroup Global
+@def      PCH_READ_LONG
+@brief   macro to set a specified bit for a variable
+*/
+#define PCH_SET_BIT(var, bit) ((var) |= (1<<(bit)))
+
+/*! @ingroup Global
+@def      PCH_READ_LONG
+@brief   macro to clear a specified bit for a variable
+*/
+#define PCH_CLR_BIT(var, bit) ((var) &= ~(1<<(bit)))
+
+#endif
diff -urN linux-2.6.33.1/drivers/dma/pch_dma/pch_debug.h
topcliff-2.6.33.1/drivers/dma/pch_dma/pch_debug.h
--- linux-2.6.33.1/drivers/dma/pch_dma/pch_debug.h 1970-01-01
09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/dma/pch_dma/pch_debug.h 2010-04-27
11:46:20.000000000 +0900
@@ -0,0 +1,58 @@
+/*!
+ * @file pch_debug.h
+ * @brief Provides the macro definitions used for debugging.
+ * @version 1.0.0.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307,
USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ *
+ *
+ * created:
+ * OKISEMI 04/14/2010
+ *
+ */
+
+#ifndef __PCH_DEBUG_H__
+#define __PCH_DEBUG_H__
+
+#ifdef MODULE
+#define PCH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n",\
+       THIS_MODULE->name, ##args)
+#else
+#define PCH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n" ,\
+        __FILE__, ##args)
+#endif
+
+
+#ifdef DEBUG
+ #define PCH_DEBUG(fmt, args...) PCH_LOG(KERN_DEBUG, fmt, ##args)
+#else
+ #define PCH_DEBUG(fmt, args...)
+#endif
+
+#ifdef PCH_TRACE_ENABLED
+ #define PCH_TRACE PCH_DEBUG
+#else
+ #define PCH_TRACE(fmt, args...)
+#endif
+
+#define PCH_TRACE_ENTER PCH_TRACE("Enter %s", __func__)
+#define PCH_TRACE_EXIT  PCH_TRACE("Exit %s", __func__)
+
+
+#endif
diff -urN linux-2.6.33.1/drivers/dma/pch_dma/pch_dma_hal.c
topcliff-2.6.33.1/drivers/dma/pch_dma/pch_dma_hal.c
--- linux-2.6.33.1/drivers/dma/pch_dma/pch_dma_hal.c 1970-01-01
09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/dma/pch_dma/pch_dma_hal.c 2010-04-27
11:46:20.000000000 +0900
@@ -0,0 +1,1201 @@
+/**
+ * @file pch_dma_hal.c
+ *
+ * @brief
+ *  This file defines the PCH_DMA_CONTROLLER HAL API functions.
+ *
+ * @version 0.90
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307,
USA.
+ *
+ * <hr>
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ *
+ *
+ * created:
+ * OKISEMI 04/14/2010
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_dma_hal.h"
+
+/*! @ingroup HALLayer
+ @def  PCH_DMA_BIT_SET
+ @brief  Macro for setting selected bits of a register.
+ @remarks This macro is used to set the selected bits
+    at a given 32 bit location. Normally it is
+    used to set the bits of given register.
+*/
+#define PCH_DMA_BIT_SET(reg, bitmask) \
+   PCH_WRITE_LONG(((PCH_READ_LONG((reg)) | bitmask)), (reg))
+
+/*! @ingroup HALLayer
+ @def  PCH_DMA_BIT_CLEAR
+ @brief  Macro for re-setting selected bits of a register.
+ @remarks This macro is used to reset the selected bits
+    at a given 32 bit location. Normally it is
+    used to reset the bits of given register.
+*/
+#define PCH_DMA_BIT_CLEAR(regAddr, bitMask) \
+  PCH_WRITE_LONG((PCH_READ_LONG((regAddr)) & (~(bitMask))), \
+  (regAddr))
+
+/*! @ingroup HALLayer
+ @def  DEFAULT_CONTROL_REGISTER_VALUE
+ @brief  Macro for setting selected bits of control register.
+ @remarks This macro is used to set the mode and direction
+    bit of the control register of a specific
+    channel without affecting the settings of other
+    channels.
+*/
+#define DEFAULT_CONTROL_REGISTER_VALUE (0x33333333)
+
+/*! @ingroup HALLayer
+ @def  dma_clear_interrupt_status
+ @brief  Macro for clearing the interrupt status of the
+    DMA.
+ @remarks This macro is used to clear the interrupt status
+    bits of the DMA during handling of interrupts.
+*/
+#define dma_clear_interrupt_status(addr, stat0, stat2)  \
+do {        \
+ PCH_WRITE_LONG((stat0), ((addr) + DMA_STS0_OFFSET)); \
+ PCH_WRITE_LONG((stat2), ((addr) + DMA_STS2_OFFSET)); \
+} while (0)
+
+/*! @ingroup HALLayer
+ @def  dma_get_interrupt_status
+ @brief  Macro for getting the interrupt status of a
+    specific channel
+ @remarks This macro is used to get the interrupt status
+    of the DMA during handling of interrupts.
+*/
+#define dma_get_interrupt_status(ch, stat0, stat2)   \
+(         \
+ ((ch) < 8) ?       \
+ (((stat0) & (DMA_INTERRUPT_OCCUR << ch)) != 0)   \
+ :        \
+ (((stat2) & (DMA_INTERRUPT_OCCUR << (ch - 8))) != 0)  \
+)
+
+/*! @ingroup HALLayer
+ @def  dma_get_abort_status
+ @brief  Macro for getting the abort status of a specific
+    channel.
+ @remarks This macro is used to get the abort status
+    of the DMA during handling of interrupts.
+*/
+#define dma_get_abort_status(ch, stat0, stat2)    \
+(         \
+ ((ch) < 8) ?       \
+ (((stat0) & (DMA_ABORT_OCCUR << ch)) != 0)   \
+ :        \
+ (((stat2) & (DMA_ABORT_OCCUR << (ch - 8))) != 0)  \
+)
+
+/* Global Varibles */
+/*! @ingroup Global
+ @var  pch_dma_channel_info
+ @brief  Retains the specific channel information.
+*/
+struct pch_dma_controller_info pch_dma_channel_info[PCH_DMA_CHANNELS_MAX];
+
+/* Channel Allocation Table for DMA */
+/*! @ingroup Global
+ @var  pch_dma_channel_table
+ @brief  Retains the specific channel allocation
+    information.
+*/
+struct pch_dma_channel_alloc_table
pch_dma_channel_table[PCH_DMA_CHANNELS_MAX]
+= {
+ /* 4 channel DMA device0 (Reserved for GE.) */
+ {PCH_DMA_4CH0, PCH_DMA_TX_DATA_REQ0, PCI_DEVICE_ID_PCH_SPI, 0, 0, 0, 0},
+ {PCH_DMA_4CH0, PCH_DMA_RX_DATA_REQ0, PCI_DEVICE_ID_PCH_SPI, 1, 0, 0, 0},
+ {PCH_DMA_4CH0, 0, 0, 2, 0, 0, 0},
+ {PCH_DMA_4CH0, 0, 0, 3, 0, 0, 0},
+
+ /* 4 channel DMA device1 (Not reserved.) */
+ {PCH_DMA_4CH1, 0, 0, 0, 0, 0, 0},
+ {PCH_DMA_4CH1, 0, 0, 1, 0, 0, 0},
+ {PCH_DMA_4CH1, 0, 0, 2, 0, 0, 0},
+ {PCH_DMA_4CH1, 0, 0, 3, 0, 0, 0},
+
+ /* 4 channel DMA device2 (Not reserved.) */
+ {PCH_DMA_4CH2, 0, 0, 0, 0, 0, 0},
+ {PCH_DMA_4CH2, 0, 0, 1, 0, 0, 0},
+ {PCH_DMA_4CH2, 0, 0, 2, 0, 0, 0},
+ {PCH_DMA_4CH2, 0, 0, 3, 0, 0, 0},
+
+ /* 4 channel DMA device3 (Not reserved.) */
+ {PCH_DMA_4CH3, 0, 0, 0, 0, 0, 0},
+ {PCH_DMA_4CH3, 0, 0, 1, 0, 0, 0},
+ {PCH_DMA_4CH3, 0, 0, 2, 0, 0, 0},
+ {PCH_DMA_4CH3, 0, 0, 3, 0, 0, 0},
+
+ /* 4 channel DMA device4 (Not reserved.) */
+ {PCH_DMA_4CH4, 0, 0, 0, 0, 0, 0},
+ {PCH_DMA_4CH4, 0, 0, 1, 0, 0, 0},
+ {PCH_DMA_4CH4, 0, 0, 2, 0, 0, 0},
+ {PCH_DMA_4CH4, 0, 0, 3, 0, 0, 0},
+
+ /* 8 channel DMA device0 (Reserved for GE.) */
+ {PCH_DMA_8CH0, PCH_DMA_TX_DATA_REQ0, PCI_DEVICE_ID_PCH_UART0, 0, 0, 0,
+  0},
+ {PCH_DMA_8CH0, PCH_DMA_RX_DATA_REQ0, PCI_DEVICE_ID_PCH_UART0, 1, 0, 0,
+  0},
+ {PCH_DMA_8CH0, PCH_DMA_TX_DATA_REQ0, PCI_DEVICE_ID_PCH_UART1, 2, 0, 0,
+  0},
+ {PCH_DMA_8CH0, PCH_DMA_RX_DATA_REQ0, PCI_DEVICE_ID_PCH_UART1, 3, 0, 0,
+  0},
+ {PCH_DMA_8CH0, PCH_DMA_TX_DATA_REQ0, PCI_DEVICE_ID_PCH_UART2, 4, 0, 0,
+  0},
+ {PCH_DMA_8CH0, PCH_DMA_RX_DATA_REQ0, PCI_DEVICE_ID_PCH_UART2, 5, 0, 0,
+  0},
+ {PCH_DMA_8CH0, PCH_DMA_TX_DATA_REQ0, PCI_DEVICE_ID_PCH_UART3, 6, 0, 0,
+  0},
+ {PCH_DMA_8CH0, PCH_DMA_RX_DATA_REQ0, PCI_DEVICE_ID_PCH_UART3, 7, 0, 0,
+  0},
+
+ /* 8 channel DMA device1 */
+ {PCH_DMA_8CH1, 0, 0, 0, 0, 0, 0},
+ {PCH_DMA_8CH1, 0, 0, 1, 0, 0, 0},
+ {PCH_DMA_8CH1, 0, 0, 2, 0, 0, 0},
+ {PCH_DMA_8CH1, 0, 0, 3, 0, 0, 0},
+ {PCH_DMA_8CH1, 0, 0, 4, 0, 0, 0},
+ {PCH_DMA_8CH1, 0, 0, 5, 0, 0, 0},
+ {PCH_DMA_8CH1, 0, 0, 6, 0, 0, 0},
+ {PCH_DMA_8CH1, 0, 0, 7, 0, 0, 0},
+
+ /* 8 channel DMA device2 */
+ {PCH_DMA_8CH2, 0, 0, 0, 0, 0, 0},
+ {PCH_DMA_8CH2, 0, 0, 1, 0, 0, 0},
+ {PCH_DMA_8CH2, 0, 0, 2, 0, 0, 0},
+ {PCH_DMA_8CH2, 0, 0, 3, 0, 0, 0},
+ {PCH_DMA_8CH2, 0, 0, 4, 0, 0, 0},
+ {PCH_DMA_8CH2, 0, 0, 5, 0, 0, 0},
+ {PCH_DMA_8CH2, 0, 0, 6, 0, 0, 0},
+ {PCH_DMA_8CH2, 0, 0, 7, 0, 0, 0},
+
+ /* 8 channel DMA device3 (Doubts in allocating.) */
+ {PCH_DMA_8CH3, 0, 0, 0, 0, 0, 0},
+ {PCH_DMA_8CH3, 0, 0, 1, 0, 0, 0},
+ {PCH_DMA_8CH3, 0, 0, 2, 0, 0, 0},
+ {PCH_DMA_8CH3, 0, 0, 3, 0, 0, 0},
+ {PCH_DMA_8CH3, 0, 0, 4, 0, 0, 0},
+ {PCH_DMA_8CH3, 0, 0, 5, 0, 0, 0},
+ {PCH_DMA_8CH3, 0, 0, 6, 0, 0, 0},
+ {PCH_DMA_8CH3, 0, 0, 7, 0, 0, 0},
+
+ /* 12 channel DMA device0 */
+ {PCH_DMA_12CH0, 0, 0, 0, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 1, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 2, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 3, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 4, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 5, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 6, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 7, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 8, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 9, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 10, 0, 0, 0},
+ {PCH_DMA_12CH0, 0, 0, 11, 0, 0, 0}
+};
+
+/* Function Definitions */
+
+/*! @ingroup HALLayerAPI
+ @fn   void __init dma_init(u32 base, u32 dev_type)
+ @brief  Initializes local data structures for the DMAC device.
+ @remarks This function is called when a DMA device is detected.
+    It initializes the data structures associated
+    with the obtained device. The main tasks
+    performed by this function are:
+    - Waits until the status of a DMA channel
+    becomes idle and then disables it.
+    - Initializes the data structures that can
+    be used further.
+
+ @param  base  [@ref IN] The base address.
+ @param  dev_type [@ref IN] The type of the device.
+
+ @return None.
+
+ @see
+   - pch_dma_probe
+ */
+
+void __init dma_init(u32 base, u32 dev_type)
+{
+ int i;
+ u32 counter;
+ u16 DMAStatus;
+
+ for (i = 0; i < PCH_DMA_CHANNELS_MAX; i++) {
+  if (pch_dma_channel_table[i].dma_dev_id == dev_type) {
+   counter = COUNTER_LIMIT;
+
+   pch_dma_channel_table[i].ch_found = 1;
+   pch_dma_channel_table[i].ch_alloced = 0;
+   pch_dma_channel_table[i].base = base;
+
+   do {
+    get_dma_status(i, &DMAStatus);
+   } while ((counter--) && (DMAStatus != DMA_STATUS_IDLE));
+
+   (void)dma_disable_ch(i);
+   PCH_DEBUG("dma_init -> Channel %d disabled.\n", i);
+
+   (void)dma_enable_disable_interrupt
+       (i, PCH_DMA_INTERRUPT_DISABLE);
+   PCH_DEBUG
+       ("dma_init -> Interrupt disabled for channel %d.\n",
+        i);
+  }
+ }
+
+ PCH_DEBUG("Function dma_init invoked successfully.\n");
+}
+
+/*! @ingroup HALLayerAPI
+ @fn   void dma_exit(u32 dev_type)
+ @brief  De-initializes the DMA device.
+ @remarks The main tasks performed by this function are:
+    - Waits for a small interval for each channel
+    if the channel is not idle so that it can
+    complete its transfer.
+    - Disables the channel.
+    - Disables the concerned interrupt.
+
+ @param  dev_type [@ref IN] The type of the device.
+
+ @return  None
+
+ @see
+  - pch_dma_remove
+  - pch_dma_suspend
+*/
+void dma_exit(u32 dev_type)
+{
+ int i;
+ u32 counter;
+ u16 DMAStatus;
+
+ for (i = 0; i < PCH_DMA_CHANNELS_MAX; i++) {
+  if (pch_dma_channel_table[i].dma_dev_id == dev_type &&
+      pch_dma_channel_table[i].ch_found == 1) {
+   counter = COUNTER_LIMIT;
+   get_dma_status(i, &DMAStatus);
+
+   while ((counter > 0) &&
+          (DMAStatus != DMA_STATUS_IDLE)) {
+    counter--;
+    get_dma_status(i, &DMAStatus);
+   }
+
+   (void)dma_disable_ch(i);
+   PCH_DEBUG("dma_exit -> Channel %d disabled.\n", i);
+
+   (void)dma_enable_disable_interrupt
+       (i, PCH_DMA_INTERRUPT_DISABLE);
+   PCH_DEBUG("dma_exit -> Interrupt disabled for channel "
+      "%d.\n", i);
+  }
+ }
+
+ PCH_DEBUG("Function dma_exit invoked successfully.\n");
+}
+
+/*! @ingroup HALLayerAPI
+ @fn int dma_set_mode(int channel,
+   struct pch_dma_mode_param stModeParam)
+ @brief  Sets the Mode of transfer for DMA.
+ @remarks Does the setting of direction of transfer, access size
+    type and transfer mode. This function does not
+    perform any register write. The main tasks
+    performed by this function are:
+    - Set the DMATransferDirection field of @ref
+    pch_dma_channel_info with the direction of
+    transfer specified.
+    - Set the DMAAccessSize field of @ref
+    pch_dma_channel_info with the Access Size Type
+    specified.
+    - Set the DMATransferMode field of @ref
+    pch_dma_channel_info structure with the DMA mode
+    specified.
+
+ @param channel [@ref IN] The channel for which mode is to be set.
+ @param stModeParam [@ref IN] Structure which contains the
+     parameters for the setting of Mode.
+
+ @return  int
+   - @ref PCH_DMA_SUCCESS --> On success.
+
+ @see
+   - pch_set_dma_mode
+ */
+int dma_set_mode(int channel, struct pch_dma_mode_param stModeParam)
+{
+ pch_dma_channel_info[channel].DMAAccessSize = stModeParam.DMASizeType;
+ pch_dma_channel_info[channel].DMATransferMode =
+     stModeParam.DMATransferMode;
+ pch_dma_channel_info[channel].DMATransferDirection =
+     stModeParam.TransferDirection;
+
+ PCH_DEBUG("Function dma_set_mode returns %d.\n", PCH_DMA_SUCCESS);
+ return PCH_DMA_SUCCESS;
+}
+
+/*! @ingroup HALLayerAPI
+ @fn  int dma_set_addr(int channel, u32 iaddr, u32 oaddr)
+ @brief  Sets the Inside and Outside address in the case
+    of ONE SHOT MODE
+ @remarks This function updates Inside address and outside
+    address to be set in ONE SHOT mode. The main
+    tasks performed by this function are:
+    - Set the field in_addr of the @ref
+    pch_dma_channel_info structure of the
+    corresponding channel to the value of the
+    argument iaddr.
+    - Set the field out_addr of the @ref
+    pch_dma_channle_info structure of the
+    corresponding channel to the value of the
+    argument oaddr.
+
+ @param  channel [@ref IN] Channel for which addresses is
+    to be set.
+ @param  iaddr [@ref IN] Inside address to be set
+ @param  oaddr [@ref IN] Outside address to be set
+
+ @return  int
+   - @ref PCH_DMA_SUCCESS --> On Success.
+
+ @see
+   - pch_set_dma_addr
+
+  */
+int dma_set_addr(int channel, u32 iaddr, u32 oaddr)
+{
+ pch_dma_channel_info[channel].in_addr = iaddr;
+ pch_dma_channel_info[channel].out_addr = oaddr;
+
+ PCH_DEBUG("Function dma_set_addr returns %d.\n", PCH_DMA_SUCCESS);
+ return PCH_DMA_SUCCESS;
+}
+
+/*! @ingroup HALLayerAPI
+ @fn   int dma_enable_ch(int channel)
+ @brief  Enables the DMA channel specified.
+ @remarks This function sets the entire DMA settings such as
+    the transfer direction, transfer mode and
+    enables the channel. The main tasks performed by
+    this function are:
+    - Sets the transfer direction.
+    - Sets the transfer mode.
+    - Enabling the channel.
+
+ @param  channel  [@ref IN] Channel number that
+     is to be enabled.
+
+ @return  int
+   - @ref PCH_DMA_SUCCESS --> On success.
+
+ @see
+   - pch_enable_dma
+ */
+int dma_enable_ch(int channel)
+{
+ u32 base_address;
+ u16 transfer_mode;
+ u32 ctl0;
+ u32 ctrl_val = DEFAULT_CONTROL_REGISTER_VALUE;
+ int ch;
+
+ /* Marking the channel as enabled. */
+ pch_dma_channel_info[channel].bChEnabled = 1;
+
+ ch = pch_dma_channel_table[channel].channel;
+ base_address = pch_dma_channel_table[channel].base;
+
+ ctl0 = 0;
+
+ /* Setting of transfer direction. */
+ if (pch_dma_channel_info[channel].DMATransferDirection ==
+     PCH_DMA_DIR_OUT_TO_IN) {
+  ctl0 |= PCH_DMA_DIR_OUT_TO_IN;
+ }
+
+ /* Setting the transfer mode features. */
+ transfer_mode = pch_dma_channel_info[channel].DMATransferMode;
+
+ /* If scatter gather mode. */
+ if (transfer_mode == DMA_SCATTER_GATHER_MODE) {
+  u32 next_desc;
+
+  next_desc = ((u32) pch_dma_channel_info[channel].pHeadOfList);
+  PCH_WRITE_LONG(next_desc, (base_address + (DMA_NX_AD_OFFSET +
+          (ch * 0x10))));
+
+  ctl0 |= DMA_SCATTER_GATHER_MODE;
+ }
+ /* If one shot mode. */
+ else {
+  u32 in_address = pch_dma_channel_info[channel].in_addr;
+  u32 out_address = pch_dma_channel_info[channel].out_addr;
+  u32 access_size = pch_dma_channel_info[channel].DMAAccessSize;
+  u32 count = pch_dma_channel_info[channel].DMATransferSize;
+
+  ctl0 |= DMA_ONE_SHOT_MODE;
+
+  count |= access_size;
+
+  PCH_WRITE_LONG(in_address,
+          (base_address +
+    (DMA_IN_AD_OFFSET + (ch * 0x10))));
+  PCH_WRITE_LONG(out_address,
+          (base_address +
+    (DMA_OUT_AD_OFFSET + (ch * 0x10))));
+  PCH_WRITE_LONG(count,
+          (base_address + (DMA_SZ_OFFSET + (ch * 0x10))));
+ }
+
+ /* Enabling the interrupts. */
+ (void)dma_enable_disable_interrupt(channel, PCH_DMA_INTERRUPT_ENABLE);
+
+ /* Updating Control register. */
+ if (ch < 8) {
+  /* Clearing the three bits corresponding
+     to the mode and transfer direction of
+     specific channel.
+   */
+  ctrl_val &= ~((MSK_ALL_THREE) << (ch * DMA_SHIFT_MODE_BITS));
+
+  /* Setting the transfer mode and direction. */
+  ctrl_val |= (ctl0 << (ch * DMA_SHIFT_MODE_BITS));
+
+  /* Updating to the register. */
+  PCH_WRITE_LONG(ctrl_val, (base_address + DMA_CTL0_OFFSET));
+
+  PCH_DEBUG("dma_enable -> Control register(0) value: "
+     "%x.\n",
+     PCH_READ_LONG((base_address + DMA_CTL0_OFFSET)));
+ } else {
+  /* Clearing the three bits corresponding
+     to the mode and transfer direction of
+     specific channel.
+   */
+  ctrl_val &=
+      ~((MSK_ALL_THREE) << ((ch - 8) * DMA_SHIFT_MODE_BITS));
+
+  /* Setting the transfer mode and direction. */
+  ctrl_val |= (ctl0 << ((ch - 8) * DMA_SHIFT_MODE_BITS));
+
+  /* Updating to the register. */
+  PCH_WRITE_LONG(ctrl_val, (base_address + DMA_CTL3_OFFSET));
+
+  PCH_DEBUG("dma_enable -> Control register(3) value: "
+     "%x.\n",
+     PCH_READ_LONG((base_address + DMA_CTL3_OFFSET)));
+ }
+
+ PCH_DEBUG("Function dma_enable_ch returns %d.\n", PCH_DMA_SUCCESS);
+ return PCH_DMA_SUCCESS;
+}
+
+/*! @ingroup HALLayerAPI
+ @fn   int dma_disable_ch(int channel)
+ @brief  Disables the DMA channel specified.
+ @remarks This function performs the necessary
+    register updation in-order to disable
+    the DMA channel.
+
+ @param  channel [@ref IN] Channel to be disabled.
+
+ @return  int
+   - @ref PCH_DMA_SUCCESS
+
+ @see
+   - pch_disable_dma
+ */
+int dma_disable_ch(int channel)
+{
+ u32 base_address;
+ u16 ch;
+
+ ch = pch_dma_channel_table[channel].channel;
+ base_address = pch_dma_channel_table[channel].base;
+
+ if (channel < 8) {
+  /* Clearing the mode bits of the channel */
+  PCH_DMA_BIT_CLEAR((base_address + DMA_CTL0_OFFSET),
+      (DMA_MASK_MODE_BITS <<
+       (ch * DMA_SHIFT_MODE_BITS)));
+ } else {
+  /* Clearing the mode bits of the channel */
+  PCH_DMA_BIT_CLEAR((base_address + DMA_CTL3_OFFSET),
+      (DMA_MASK_MODE_BITS <<
+       ((ch - 8) * DMA_SHIFT_MODE_BITS)));
+ }
+
+ /* Updating the enable variable. */
+ pch_dma_channel_info[channel].bChEnabled = (u16) 0;
+
+ PCH_DEBUG("Function dma_disable_ch returns " "%d.\n", PCH_DMA_SUCCESS);
+ return PCH_DMA_SUCCESS;
+}
+
+/*! @ingroup HALLayerAPI
+ @fn   int dma_set_count (int channel, u32 count)
+ @brief  Sets the count value .
+ @remarks Updates the transfer size for ONE_SHOT_MODE
+    of DMA Transfer. The main tasks performed by
+    this function are:
+    - Set the DMATransferSize field of the
+    @ref pch_dma_channel_info structure to the
+    value of the argument count.
+
+ @param  channel  [@ref IN] Channel number for
+     which value is to be set
+ @param  count  [@ref IN] Transfer Size value.
+
+ @return  int
+   - @ref PCH_DMA_SUCCESS
+
+ @see
+   - pch_set_dma_count
+ */
+int dma_set_count(int channel, u32 count)
+{
+ pch_dma_channel_info[channel].DMATransferSize = count;
+
+ PCH_DEBUG("Function dma_set_count returns %d.\n", PCH_DMA_SUCCESS);
+ return PCH_DMA_SUCCESS;
+}
+
+/*! @ingroup HALLayerAPI
+ @fn  int dma_add_desc(int channel,
+    struct pch_dma_desc *start,
+    struct pch_dma_desc *end)
+ @brief  Adds descriptors to the existing list of descriptors.
+ @remarks This function accepts the descriptor list and appends
+    it to the existing list of descriptors. The main
+    tasks performed by this function are:
+    - Obtains the virtual address of the end of the
+    currently set descriptor list. If it is not
+    successful returns with an error.
+    - Appends the value of the argument start to the
+    nextDesc field of the descriptor pointed by the
+    pTailOfList field of the
+    @ref pch_dma_channel_info structure with the
+    value of the argument start after appropriately
+    setting the last two bits to denote
+    Follow_Next_Descriptor_Without_Interrupt.
+    - Updates the value of the argument end to the
+    pTailOfList field of the @ref
+    pch_dma_channel_info structure for the
+    corresponding channel.
+
+ @param  channel  [@ref IN] Channel number.
+ @param  start  [@ref IN] Reference to first
+      descriptor of list.
+ @param  end  [@ref IN] Reference to last
+      descriptor of list.
+
+ @return  int
+   - @ref PCH_DMA_SUCCESS --> If appending of the
+   descriptor is successful.
+
+ @see
+  - pch_add_dma_desc
+*/
+int dma_add_desc(int channel, struct pch_dma_desc *start,
+   struct pch_dma_desc *end)
+{
+ struct pch_dma_desc *desc_addr;
+
+ desc_addr = pch_dma_channel_info[channel].pTailOfList;
+
+ /* Obtaining the virtual address. */
+ desc_addr = (struct pch_dma_desc *) phys_to_virt((u32) desc_addr);
+
+ /* If virtual address calculation successful. */
+ desc_addr->nextDesc = (u32) start;
+ pch_dma_channel_info[channel].pTailOfList = end;
+
+ PCH_DEBUG("Function dma_add_desc returns %d.\n", PCH_DMA_SUCCESS);
+ return PCH_DMA_SUCCESS;
+}
+
+/*! @ingroup HALLayerAPI
+ @fn void  dma_set_callback (int channel,  void (*pch_dma_cbr)
+   ( int value,unsigned long data1),unsigned long data)
+ @brief  To set callback function.
+ @remarks Sets the callback function to be called for a channel.
+    The main task performed by this function is:
+    - Updates the callback pointer for the channel
+    in the structure pch_dma_channel_info with the
+    parameter passed.
+
+ @param  channel  [@ref IN] Channel number.
+ @param  pch_dma_cbr [@ref IN] Function pointer
+      to call back function.
+ @param  data  [@ref IN] The data to be passed to
+      the callback function during
+      invoking.
+
+ @return None.
+
+ @see
+  - pch_dma_set_callback
+  */
+void dma_set_callback(int channel,
+        void (*pch_dma_cbr) (int value, unsigned long data1),
+        unsigned long data)
+{
+ pch_dma_channel_info[channel].call_back_func_ptr = pch_dma_cbr;
+ pch_dma_channel_info[channel].callback_data = data;
+
+ PCH_DEBUG("Function dma_set_callback invoked successfully.\n");
+}
+
+/*! @ingroup HALLayerAPI
+ @fn  irqreturn_t dma_interrupt (int irq, void *dev_id)
+ @brief  Interrupt handler.
+ @remarks Handles the interrupt for the DMA. The main tasks
+    performed by this function are:
+    - Checks each DMA channels whether a DMA
+    transmission end or DMA status interrupt has
+    occurred.
+    - If a transmission end interrupt has occurred,
+    then invoke the callback function with @ref
+    PCH_DMA_END, denoting that the DMA transmission
+    has end.
+    - If a DMA abort interrupt has occurred, then
+    invoke the callback function with @ref
+    PCH_DMA_ABORT, denoting that a DMA abort has
+    occurred.
+
+ @param  irq  [@ref IN] Interrupt Request number
+ @param  dev_id [@ref IN] dev_id of device for which
+     interrupt is raised .
+
+ @return  irqreturn_t
+   - IRQ_HANDLED --> If interrupt has been processed.
+   - IRQ_NONE --> If no interrupt has been processed.
+
+ */
+irqreturn_t dma_interrupt(int irq, void *dev_id)
+{
+ irqreturn_t retval = IRQ_NONE;
+ u32 status_reg0;
+ u32 status_reg2;
+ u32 base_address;
+ u32 dev_type;
+ u32 i;
+ u16 status;
+
+ base_address = ((struct pch_dma_devices *) dev_id)->base_addr;
+ dev_type = ((struct pch_dma_devices *) dev_id)->dev_typ;
+
+ /* Reading the status registers. */
+ status_reg0 = PCH_READ_LONG((base_address + DMA_STS0_OFFSET));
+ status_reg2 = PCH_READ_LONG((base_address + DMA_STS2_OFFSET));
+ PCH_DEBUG("dma_interrupt -> Status register STS0: %x STS2: "
+    "%x.\n", status_reg0, status_reg2);
+
+ /* Clearing the interrupts. */
+ dma_clear_interrupt_status(base_address, status_reg0, status_reg2);
+
+ /* Handling the interrupts. */
+ for (i = 0; i < PCH_DMA_CHANNELS_MAX; i++) {
+  if ((pch_dma_channel_table[i].dma_dev_id == dev_type) &&
+      (pch_dma_channel_table[i].ch_alloced == 1) &&
+      (pch_dma_channel_info[i].bChEnabled == 1)
+      ) {
+   status =
+       dma_get_interrupt_status(pch_dma_channel_table
+           [i].channel, status_reg0,
+           status_reg2);
+   PCH_DEBUG
+       ("dma_interrupt -> Interrupt status for ch: %d is "
+       "%x.\n", i, status);
+
+   if (status == 1) {
+    int value = PCH_DMA_END;
+
+    status =
+        dma_get_abort_status(pch_dma_channel_table
+        [i].channel,
+        status_reg0,
+        status_reg2);
+
+    if (status == 1) {
+     value = PCH_DMA_ABORT;
+
+     PCH_DEBUG
+         ("dma_interrupt -> DMA Abort "
+         "interrupt from channel%d.\n", i);
+    }
+#ifdef DEBUG
+    else {
+     PCH_DEBUG
+         ("dma_interrupt -> DMA Completion "
+         "interrupt "
+          "from channel%d.\n", i);
+    }
+#endif
+    if (pch_dma_channel_info[i].
+        call_back_func_ptr) {
+     u32 data =
+         pch_dma_channel_info
+         [i].callback_data;
+     (pch_dma_channel_info
+      [i].call_back_func_ptr) (value, data);
+    }
+
+    /* Determining whether the channel has been
+    disabled. */
+    {
+     u32 ctrl_val;
+     s32 ch =
+         pch_dma_channel_table[i].channel;
+     u32 base_address =
+         pch_dma_channel_table[i].base;
+
+     if (ch < 8) {
+      ctrl_val =
+          PCH_READ_LONG((base_address
+           + DMA_CTL0_OFFSET));
+
+      ctrl_val &=
+          ((0x3) <<
+          (ch * DMA_SHIFT_MODE_BITS));
+     } else {
+      ctrl_val =
+          PCH_READ_LONG((base_address
+           + DMA_CTL3_OFFSET));
+      ctrl_val &=
+          ((0x3) <<
+           ((ch - 8) *
+            DMA_SHIFT_MODE_BITS));
+     }
+
+     pch_dma_channel_info[i].bChEnabled =
+         (ctrl_val != 0) ? 1 : 0;
+
+    } /* End */
+
+    retval = IRQ_HANDLED;
+   }
+  }
+ }
+
+ PCH_DEBUG("Function dma_interrupt returns %d.\n", retval);
+ return retval;
+}
+
+/*! @ingroup HALLayerAPI
+ @fn  int dma_direct_start (int channel)
+ @brief  To generate the DMA request which each Function-IP
+    transmits.
+ @remarks This function is used to initiate the DMA
+    transfer process. The main task performed by
+    this function is:
+    - Sets the value of DMAn Direct Start bit in the
+    Control register 2 to start DMA transfer on
+    channel n.
+
+ @param  channel [@ref IN] Channel number for which DMA
+      transfer is to be started.
+
+ @return  int
+   - @ref PCH_DMA_SUCCESS --> On Success.
+
+ @see
+   - pch_dma_direct_start
+ */
+int dma_direct_start(int channel)
+{
+ int ch;
+ u32 base_address;
+
+ ch = pch_dma_channel_table[channel].channel;
+ base_address = pch_dma_channel_table[channel].base;
+
+ if (ch < 8) {
+  PCH_DMA_BIT_SET((base_address + DMA_CTL2_OFFSET),
+    (DMA_DIR_START << ch));
+ } else {
+  PCH_DMA_BIT_SET((base_address + DMA_CTL2_OFFSET),
+    (DMA_DIR_START << (ch + 6)));
+ }
+
+ PCH_DEBUG("dma_direct_start -> Direct2 RegValue: "
+    "%x.\n", PCH_READ_LONG((base_address + DMA_CTL2_OFFSET)));
+
+ PCH_DEBUG("Function dma_direct_start returns "
+    "%d.\n", PCH_DMA_SUCCESS);
+ return PCH_DMA_SUCCESS;
+}
+
+/*! @ingroup HALLayerAPI
+ @fn   int dma_set_priority (int channel, int priority)
+ @brief  Set the priority.
+ @remarks Sets the priority for a channel. The main task
+    performed by this function is:
+    - Set the value of DMAn Priority Level bits for
+    the channel in the Control register1.
+
+ @param  channel [@ref IN] DMA channel number.
+ @param  priority [@ref IN] Priority to be set for
+       the DMA channel.
+
+ @return  int
+   - @ref PCH_DMA_SUCCESS --> On Success.
+
+ @see
+   - pch_set_dma_priority
+  */
+int dma_set_priority(int channel, int priority)
+{
+ int ch;
+ u32 base_address;
+ u32 reg_val;
+
+ ch = pch_dma_channel_table[channel].channel;
+ base_address = pch_dma_channel_table[channel].base;
+
+ reg_val = PCH_READ_LONG((base_address + DMA_CTL1_OFFSET));
+
+ if (ch < 8) {
+  reg_val &=
+      ~(DMA_MASK_PRIORITY_BITS << (ch * DMA_SHIFT_PRIORITY_BITS));
+  reg_val |= (((u32) priority) << (ch * DMA_SHIFT_PRIORITY_BITS));
+ } else {
+  reg_val &=
+      ~(DMA_MASK_PRIORITY_BITS <<
+        (((ch - 8) * DMA_SHIFT_PRIORITY_BITS) + 2));
+  reg_val |=
+      (((u32) priority) <<
+       (((ch - 8) * DMA_SHIFT_PRIORITY_BITS) + 2));
+ }
+
+ PCH_WRITE_LONG(reg_val, (base_address + DMA_CTL1_OFFSET));
+
+ PCH_DEBUG("Function dma_set_priority returns "
+    "%d.\n", PCH_DMA_SUCCESS);
+ return PCH_DMA_SUCCESS;
+}
+
+/*! @ingroup HALLayerAPI
+ @fn int dma_enable_disable_interrupt (int channel, int bEnable)
+ @brief  Enables or Disables Interrupts .
+ @remarks Writes the corresponding register to either
+    enable or disable interrupts. The main tasks
+    performed by this function are:
+    - If bEnable is DMA_INTERRUPT_ENABLE (1),
+    sets the DMAn Interrupt Enable bit in control
+    register2.
+    - If bEnable is DMA_INTERRUPT_DISABLE (0),
+    clears the DMAn Interrupt Enable bit in control
+    register2.
+
+ @param channel [@ref IN] Channel number
+ @param bEnable [@ref IN] Flag to indicate whether
+      to enable or disable interrupt.
+
+ @return  int
+   - @ref PCH_DMA_SUCCESS --> On Success.
+
+ @see
+  - dma_init
+  - dma_exit
+  */
+int dma_enable_disable_interrupt(int channel, int bEnable)
+{
+ u32 base_address;
+ u16 ch;
+
+ ch = pch_dma_channel_table[channel].channel;
+ base_address = pch_dma_channel_table[channel].base;
+
+ if (ch < 8) {
+  if (PCH_DMA_INTERRUPT_ENABLE == bEnable) {
+   PCH_DMA_BIT_SET((base_address + DMA_CTL2_OFFSET),
+     (DMA_INTERRUPT_BIT << ch));
+  } else { /* if(bEnable == PCH_DMA_INTERRUPT_DISABLE) */
+
+   PCH_DMA_BIT_CLEAR((base_address + DMA_CTL2_OFFSET),
+       (DMA_INTERRUPT_BIT << ch));
+  }
+
+ } else {
+  if (PCH_DMA_INTERRUPT_ENABLE == bEnable) {
+   PCH_DMA_BIT_SET((base_address + DMA_CTL2_OFFSET),
+     (DMA_INTERRUPT_BIT << (ch + 8)));
+  } else { /* if(bEnable == PCH_DMA_INTERRUPT_DISABLE) */
+
+   PCH_DMA_BIT_CLEAR((base_address + DMA_CTL2_OFFSET),
+       (DMA_INTERRUPT_BIT << (ch + 8)));
+  }
+ }
+
+ PCH_DEBUG("dma_enable_disable_interrupt -> CTL2 Register Value: "
+    "%x.\n", PCH_READ_LONG((base_address + DMA_CTL2_OFFSET)));
+
+ PCH_DEBUG("Function dma_enable_disable_interrupt returns "
+    "%d.\n", PCH_DMA_SUCCESS);
+ return PCH_DMA_SUCCESS;
+}
+
+/*! @ingroup HALLayerAPI
+ @fn  void get_dma_status(int channel, u16 *pDMAStatus)
+ @brief  Gets the Status of DMA.
+ @remarks Gets the status of the specified DMA Channel. The
+    main task performed by this function is:
+    - Reads the data in the DMAn (for channel .n.)
+    Status bit of Status register0 (4ch or 8ch) or
+    Status register2 (12ch) and copy the value into
+    pDMAStatus.
+
+ @param  channel  [@ref IN]  Channel number.
+ @param  pDMAStatus [@ref INOUT] Address of variable to
+      which
+      status information is copied.
+
+ @return None.
+
+ @see
+  - dma_exit
+  - dma_init
+  - pch_set_dma_mode
+  - pch_set_dma_addr
+  - pch_set_dma_count
+  - pch_set_dma_desc
+  - pch_add_dma_desc

--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH] Topcliff DMA: Add the DMA driver [1/4], Masayuki Ohtake, (Tue Apr 27, 4:01 am)