---
 drivers/dma/Kconfig                |    9 
 drivers/dma/Makefile               |    1 
 drivers/dma/pch_dma/Makefile       |    5 
 drivers/dma/pch_dma/pch_common.h   |  146 ++++
 drivers/dma/pch_dma/pch_debug.h    |   60 +
 drivers/dma/pch_dma/pch_dma_hal.c  | 1203 +++++++++++++++++++++++++++++++++++++
 drivers/dma/pch_dma/pch_dma_hal.h  |  594 ++++++++++++++++++
 drivers/dma/pch_dma/pch_dma_main.c | 1026 +++++++++++++++++++++++++++++++
 drivers/dma/pch_dma/pch_dma_main.h |  264 ++++++++
 drivers/dma/pch_dma/pch_dma_pci.c  |  694 +++++++++++++++++++++
 drivers/dma/pch_dma/pch_dma_pci.h  |   74 ++
 11 files changed, 4076 insertions(+)

--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -51,6 +51,15 @@ config LNW_DMA_DEBUG
 	help
 	  Enable logging in the LNW DMA drivers
 
+config PCH_UART_DMA
+	tristate "PCH DMA Controller"
+	depends on PCI && SERIAL_8250_PCH_DMA
+	select DMA_ENGINE
+	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
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -14,4 +14,5 @@ obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
 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/
 obj-$(CONFIG_TIMB_DMA) += timb_dma.o
--- /dev/null
+++ b/drivers/dma/pch_dma/Makefile
@@ -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
--- /dev/null
+++ b/drivers/dma/pch_dma/pch_common.h
@@ -0,0 +1,146 @@
+/*!
+ * @file ioh_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.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_COMMON_H__
+#define __IOH_COMMON_H__
+
+/*! @ingroup	Global
+@def		    IOH_WRITE8
+@brief			Macro for writing 8 bit data to an io/mem address
+*/
+#define IOH_WRITE8(val, addr)   iowrite8((val), (void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_LOG
+@brief			Macro for writing 16 bit data to an io/mem address
+*/
+#define IOH_WRITE16(val, addr)  iowrite16((val), (void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_LOG
+@brief			Macro for writing 32 bit data to an io/mem address
+*/
+#define IOH_WRITE32(val, addr)  iowrite32((val), (void __iomem *)(addr))
+
+/*! @ingroup	Global
+@def		    IOH_READ8
+@brief			Macro for reading 8 bit data from an io/mem address
+*/
+#define IOH_READ8(addr)   ioread8((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_READ16
+@brief			Macro for reading 16 bit data from an io/mem address
+*/
+#define IOH_READ16(addr)  ioread16((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_READ32
+@brief			Macro for reading 32 bit data from an io/mem address
+*/
+#define IOH_READ32(addr)  ioread32((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_WRITE32_F
+@brief			Macro for writing 32 bit data to an io/mem address
+*/
+#define IOH_WRITE32_F(val, addr) do \
+	{ IOH_WRITE32((val), (addr)); (void)IOH_READ32((addr)); } while (0);
+
+/*! @ingroup	Global
+@def		    IOH_WRITE_BYTE
+@brief			Macro for writing 1 byte data to an io/mem address
+*/
+#define IOH_WRITE_BYTE IOH_WRITE8
+/*! @ingroup	Global
+@def		    IOH_WRITE_WORD
+@brief			Macro for writing 1 word data to an io/mem address
+*/
+#define IOH_WRITE_WORD IOH_WRITE16
+/*! @ingroup	Global
+@def		    IOH_WRITE_LONG
+@brief			Macro for writing long data to an io/mem address
+*/
+#define IOH_WRITE_LONG IOH_WRITE32
+
+/*! @ingroup	Global
+@def		    IOH_READ_BYTE
+@brief			Macro for reading 1 byte data from an io/mem address
+*/
+#define IOH_READ_BYTE  IOH_READ8
+/*! @ingroup	Global
+@def		    IOH_READ_WORD
+@brief			Macro for reading 1 word data from an io/mem address
+*/
+#define IOH_READ_WORD  IOH_READ16
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			Macro for reading long data from an io/mem address
+*/
+#define IOH_READ_LONG  IOH_READ32
+
+/* Bit Manipulation Macros */
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to set a specified bit(mask) at the
+			specified address
+*/
+#define IOH_SET_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) |\
+							 (bitmask)), (addr))
+
+/*! @ingroup	Global
+@def	    IOH_READ_LONG
+@brief		macro to clear a specified bit(mask) at the specified address
+*/
+#define IOH_CLR_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) &\
+							 ~(bitmask)), (addr))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to set a specified bitmask for a variable
+*/
+#define IOH_SET_BITMSK(var, bitmask) ((var) |= (bitmask))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to clear a specified bitmask for a variable
+*/
+#define IOH_CLR_BITMSK(var, bitmask) ((var) &= (~(bitmask)))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to set a specified bit for a variable
+*/
+#define IOH_SET_BIT(var, bit) ((var) |= (1<<(bit)))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to clear a specified bit for a variable
+*/
+#define IOH_CLR_BIT(var, bit) ((var) &= ~(1<<(bit)))
+
+#endif
--- /dev/null
+++ b/drivers/dma/pch_dma/pch_debug.h
@@ -0,0 +1,60 @@
+/*!
+ * @file ioh_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.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_DEBUG_H__
+#define __IOH_DEBUG_H__
+
+#ifdef MODULE
+#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n",\
+						 THIS_MODULE->name, ##args)
+#else
+#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n" ,\
+							 __FILE__, ##args)
+#endif
+
+
+#ifdef DEBUG
+	#define IOH_DEBUG(fmt, args...) IOH_LOG(KERN_DEBUG, fmt, ##args)
+#else
+	#define IOH_DEBUG(fmt, args...)
+#endif
+
+#ifdef IOH_TRACE_ENABLED
+	#define IOH_TRACE IOH_DEBUG
+#else
+	#define IOH_TRACE(fmt, args...)
+#endif
+
+#define IOH_TRACE_ENTER IOH_TRACE("Enter %s", __func__)
+#define IOH_TRACE_EXIT 	IOH_TRACE("Exit %s", __func__)
+
+
+#endif
--- /dev/null
+++ b/drivers/dma/pch_dma/pch_dma_hal.c
@@ -0,0 +1,1203 @@
+/**
+ * @file ioh_dma_hal.c
+ *
+ * @brief
+ *		This file defines the IOH_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.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 08/14/2009
+ *
+ */
+
+#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		IOH_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 IOH_DMA_BIT_SET(reg, bitmask) \
+		 IOH_WRITE_LONG(((IOH_READ_LONG((reg)) | bitmask)), (reg))
+
+/*!	@ingroup	HALLayer
+	@def		IOH_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 IOH_DMA_BIT_CLEAR(regAddr, bitMask) \
+		IOH_WRITE_LONG((IOH_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 {								\
+	IOH_WRITE_LONG((stat0), ((addr) + DMA_STS0_OFFSET));	\
+	IOH_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		ioh_dma_channel_info
+	@brief		Retains the specific channel information.
+*/
+struct ioh_dma_controller_info ioh_dma_channel_info[IOH_DMA_CHANNELS_MAX];
+
+/* Channel Allocation Table for DMA */
+/*!	@ingroup	Global
+	@var		ioh_dma_channel_table
+	@brief		Retains the specific channel allocation
+				information.
+*/
+struct ioh_dma_channel_alloc_table ioh_dma_channel_table[IOH_DMA_CHANNELS_MAX]
+= {
+	/* 4 channel DMA device0 (Reserved for GE.) */
+	{IOH_DMA_4CH0, IOH_DMA_TX_DATA_REQ0, PCI_DEVICE_ID_IOH_SPI, 0, 0, 0, 0},
+	{IOH_DMA_4CH0, IOH_DMA_RX_DATA_REQ0, PCI_DEVICE_ID_IOH_SPI, 1, 0, 0, 0},
+	{IOH_DMA_4CH0, 0, 0, 2, 0, 0, 0},
+	{IOH_DMA_4CH0, 0, 0, 3, 0, 0, 0},
+
+	/* 4 channel DMA device1 (Not reserved.) */
+	{IOH_DMA_4CH1, 0, 0, 0, 0, 0, 0},
+	{IOH_DMA_4CH1, 0, 0, 1, 0, 0, 0},
+	{IOH_DMA_4CH1, 0, 0, 2, 0, 0, 0},
+	{IOH_DMA_4CH1, 0, 0, 3, 0, 0, 0},
+
+	/* 4 channel DMA device2 (Not reserved.) */
+	{IOH_DMA_4CH2, 0, 0, 0, 0, 0, 0},
+	{IOH_DMA_4CH2, 0, 0, 1, 0, 0, 0},
+	{IOH_DMA_4CH2, 0, 0, 2, 0, 0, 0},
+	{IOH_DMA_4CH2, 0, 0, 3, 0, 0, 0},
+
+	/* 4 channel DMA device3 (Not reserved.) */
+	{IOH_DMA_4CH3, 0, 0, 0, 0, 0, 0},
+	{IOH_DMA_4CH3, 0, 0, 1, 0, 0, 0},
+	{IOH_DMA_4CH3, 0, 0, 2, 0, 0, 0},
+	{IOH_DMA_4CH3, 0, 0, 3, 0, 0, 0},
+
+	/* 4 channel DMA device4 (Not reserved.) */
+	{IOH_DMA_4CH4, 0, 0, 0, 0, 0, 0},
+	{IOH_DMA_4CH4, 0, 0, 1, 0, 0, 0},
+	{IOH_DMA_4CH4, 0, 0, 2, 0, 0, 0},
+	{IOH_DMA_4CH4, 0, 0, 3, 0, 0, 0},
+
+	/* 8 channel DMA device0 (Reserved for GE.) */
+	{IOH_DMA_8CH0, IOH_DMA_TX_DATA_REQ0, PCI_DEVICE_ID_IOH_UART0, 0, 0, 0,
+	 0},
+	{IOH_DMA_8CH0, IOH_DMA_RX_DATA_REQ0, PCI_DEVICE_ID_IOH_UART0, 1, 0, 0,
+	 0},
+	{IOH_DMA_8CH0, IOH_DMA_TX_DATA_REQ0, PCI_DEVICE_ID_IOH_UART1, 2, 0, 0,
+	 0},
+	{IOH_DMA_8CH0, IOH_DMA_RX_DATA_REQ0, PCI_DEVICE_ID_IOH_UART1, 3, 0, 0,
+	 0},
+	{IOH_DMA_8CH0, IOH_DMA_TX_DATA_REQ0, PCI_DEVICE_ID_IOH_UART2, 4, 0, 0,
+	 0},
+	{IOH_DMA_8CH0, IOH_DMA_RX_DATA_REQ0, PCI_DEVICE_ID_IOH_UART2, 5, 0, 0,
+	 0},
+	{IOH_DMA_8CH0, IOH_DMA_TX_DATA_REQ0, PCI_DEVICE_ID_IOH_UART3, 6, 0, 0,
+	 0},
+	{IOH_DMA_8CH0, IOH_DMA_RX_DATA_REQ0, PCI_DEVICE_ID_IOH_UART3, 7, 0, 0,
+	 0},
+
+	/* 8 channel DMA device1 */
+	{IOH_DMA_8CH1, 0, 0, 0, 0, 0, 0},
+	{IOH_DMA_8CH1, 0, 0, 1, 0, 0, 0},
+	{IOH_DMA_8CH1, 0, 0, 2, 0, 0, 0},
+	{IOH_DMA_8CH1, 0, 0, 3, 0, 0, 0},
+	{IOH_DMA_8CH1, 0, 0, 4, 0, 0, 0},
+	{IOH_DMA_8CH1, 0, 0, 5, 0, 0, 0},
+	{IOH_DMA_8CH1, 0, 0, 6, 0, 0, 0},
+	{IOH_DMA_8CH1, 0, 0, 7, 0, 0, 0},
+
+	/* 8 channel DMA device2 */
+	{IOH_DMA_8CH2, 0, 0, 0, 0, 0, 0},
+	{IOH_DMA_8CH2, 0, 0, 1, 0, 0, 0},
+	{IOH_DMA_8CH2, 0, 0, 2, 0, 0, 0},
+	{IOH_DMA_8CH2, 0, 0, 3, 0, 0, 0},
+	{IOH_DMA_8CH2, 0, 0, 4, 0, 0, 0},
+	{IOH_DMA_8CH2, 0, 0, 5, 0, 0, 0},
+	{IOH_DMA_8CH2, 0, 0, 6, 0, 0, 0},
+	{IOH_DMA_8CH2, 0, 0, 7, 0, 0, 0},
+
+	/* 8 channel DMA device3 (Doubts in allocating.) */
+	{IOH_DMA_8CH3, 0, 0, 0, 0, 0, 0},
+	{IOH_DMA_8CH3, 0, 0, 1, 0, 0, 0},
+	{IOH_DMA_8CH3, 0, 0, 2, 0, 0, 0},
+	{IOH_DMA_8CH3, 0, 0, 3, 0, 0, 0},
+	{IOH_DMA_8CH3, 0, 0, 4, 0, 0, 0},
+	{IOH_DMA_8CH3, 0, 0, 5, 0, 0, 0},
+	{IOH_DMA_8CH3, 0, 0, 6, 0, 0, 0},
+	{IOH_DMA_8CH3, 0, 0, 7, 0, 0, 0},
+
+	/* 12 channel DMA device0 */
+	{IOH_DMA_12CH0, 0, 0, 0, 0, 0, 0},
+	{IOH_DMA_12CH0, 0, 0, 1, 0, 0, 0},
+	{IOH_DMA_12CH0, 0, 0, 2, 0, 0, 0},
+	{IOH_DMA_12CH0, 0, 0, 3, 0, 0, 0},
+	{IOH_DMA_12CH0, 0, 0, 4, 0, 0, 0},
+	{IOH_DMA_12CH0, 0, 0, 5, 0, 0, 0},
+	{IOH_DMA_12CH0, 0, 0, 6, 0, 0, 0},
+	{IOH_DMA_12CH0, 0, 0, 7, 0, 0, 0},
+	{IOH_DMA_12CH0, 0, 0, 8, 0, 0, 0},
+	{IOH_DMA_12CH0, 0, 0, 9, 0, 0, 0},
+	{IOH_DMA_12CH0, 0, 0, 10, 0, 0, 0},
+	{IOH_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
+			- ioh_dma_probe
+ */
+
+void __init dma_init(u32 base, u32 dev_type)
+{
+	int i;
+	u32 counter;
+	u16 DMAStatus;
+
+	for (i = 0; i < IOH_DMA_CHANNELS_MAX; i++) {
+		if (ioh_dma_channel_table[i].dma_dev_id == dev_type) {
+			counter = COUNTER_LIMIT;
+
+			ioh_dma_channel_table[i].ch_found = 1;
+			ioh_dma_channel_table[i].ch_alloced = 0;
+			ioh_dma_channel_table[i].base = base;
+
+			do {
+				get_dma_status(i, &DMAStatus);
+			} while ((counter--) && (DMAStatus != DMA_STATUS_IDLE));
+
+			(void)dma_disable_ch(i);
+			IOH_DEBUG("dma_init -> Channel %d disabled.\n", i);
+
+			(void)dma_enable_disable_interrupt
+			    (i, IOH_DMA_INTERRUPT_DISABLE);
+			IOH_DEBUG
+			    ("dma_init -> Interrupt disabled for channel %d.\n",
+			     i);
+		}
+	}
+
+	IOH_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
+		- ioh_dma_remove
+		- ioh_dma_suspend
+*/
+void dma_exit(u32 dev_type)
+{
+	int i;
+	u32 counter;
+	u16 DMAStatus;
+
+	for (i = 0; i < IOH_DMA_CHANNELS_MAX; i++) {
+		if (ioh_dma_channel_table[i].dma_dev_id == dev_type &&
+		    ioh_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);
+			IOH_DEBUG("dma_exit -> Channel %d disabled.\n", i);
+
+			(void)dma_enable_disable_interrupt
+			    (i, IOH_DMA_INTERRUPT_DISABLE);
+			IOH_DEBUG("dma_exit -> Interrupt disabled for channel "
+				  "%d.\n", i);
+		}
+	}
+
+	IOH_DEBUG("Function dma_exit invoked successfully.\n");
+}
+
+/*!	@ingroup	HALLayerAPI
+	@fn	int dma_set_mode(int channel,
+			struct ioh_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
+				ioh_dma_channel_info with the direction of
+				transfer specified.
+				- Set the DMAAccessSize field of @ref
+				ioh_dma_channel_info with the Access Size Type
+				specified.
+				- Set the DMATransferMode field of @ref
+				ioh_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 IOH_DMA_SUCCESS	--> On success.
+
+	@see
+			- ioh_set_dma_mode
+ */
+int dma_set_mode(int channel, struct ioh_dma_mode_param stModeParam)
+{
+	ioh_dma_channel_info[channel].DMAAccessSize = stModeParam.DMASizeType;
+	ioh_dma_channel_info[channel].DMATransferMode =
+	    stModeParam.DMATransferMode;
+	ioh_dma_channel_info[channel].DMATransferDirection =
+	    stModeParam.TransferDirection;
+
+	IOH_DEBUG("Function dma_set_mode returns %d.\n", IOH_DMA_SUCCESS);
+	return IOH_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
+				ioh_dma_channel_info structure of the
+				corresponding channel to the value of the
+				argument iaddr.
+				- Set the field out_addr of the @ref
+				ioh_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 IOH_DMA_SUCCESS	--> On Success.
+
+	@see
+			- ioh_set_dma_addr
+
+  */
+int dma_set_addr(int channel, u32 iaddr, u32 oaddr)
+{
+	ioh_dma_channel_info[channel].in_addr = iaddr;
+	ioh_dma_channel_info[channel].out_addr = oaddr;
+
+	IOH_DEBUG("Function dma_set_addr returns %d.\n", IOH_DMA_SUCCESS);
+	return IOH_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 IOH_DMA_SUCCESS	--> On success.
+
+	@see
+			- ioh_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. */
+	ioh_dma_channel_info[channel].bChEnabled = 1;
+
+	ch = ioh_dma_channel_table[channel].channel;
+	base_address = ioh_dma_channel_table[channel].base;
+
+	ctl0 = 0;
+
+	/* Setting of transfer direction. */
+	if (ioh_dma_channel_info[channel].DMATransferDirection ==
+	    IOH_DMA_DIR_OUT_TO_IN) {
+		ctl0 |= IOH_DMA_DIR_OUT_TO_IN;
+	}
+
+	/* Setting the transfer mode features. */
+	transfer_mode = ioh_dma_channel_info[channel].DMATransferMode;
+
+	/* If scatter gather mode. */
+	if (transfer_mode == DMA_SCATTER_GATHER_MODE) {
+		u32 next_desc;
+
+		next_desc = ((u32) ioh_dma_channel_info[channel].pHeadOfList);
+		IOH_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 = ioh_dma_channel_info[channel].in_addr;
+		u32 out_address = ioh_dma_channel_info[channel].out_addr;
+		u32 access_size = ioh_dma_channel_info[channel].DMAAccessSize;
+		u32 count = ioh_dma_channel_info[channel].DMATransferSize;
+
+		ctl0 |= DMA_ONE_SHOT_MODE;
+
+		count |= access_size;
+
+		IOH_WRITE_LONG(in_address,
+			       (base_address +
+				(DMA_IN_AD_OFFSET + (ch * 0x10))));
+		IOH_WRITE_LONG(out_address,
+			       (base_address +
+				(DMA_OUT_AD_OFFSET + (ch * 0x10))));
+		IOH_WRITE_LONG(count,
+			       (base_address + (DMA_SZ_OFFSET + (ch * 0x10))));
+	}
+
+	/* Enabling the interrupts. */
+	(void)dma_enable_disable_interrupt(channel, IOH_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. */
+		IOH_WRITE_LONG(ctrl_val, (base_address + DMA_CTL0_OFFSET));
+
+		IOH_DEBUG("dma_enable -> Control register(0) value: "
+			  "%x.\n",
+			  IOH_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. */
+		IOH_WRITE_LONG(ctrl_val, (base_address + DMA_CTL3_OFFSET));
+
+		IOH_DEBUG("dma_enable -> Control register(3) value: "
+			  "%x.\n",
+			  IOH_READ_LONG((base_address + DMA_CTL3_OFFSET)));
+	}
+
+	IOH_DEBUG("Function dma_enable_ch returns %d.\n", IOH_DMA_SUCCESS);
+	return IOH_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 IOH_DMA_SUCCESS
+
+	@see
+			- ioh_disable_dma
+ */
+int dma_disable_ch(int channel)
+{
+	u32 base_address;
+	u16 ch;
+
+	ch = ioh_dma_channel_table[channel].channel;
+	base_address = ioh_dma_channel_table[channel].base;
+
+	if (channel < 8) {
+		/* Clearing the mode bits of the channel */
+		IOH_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 */
+		IOH_DMA_BIT_CLEAR((base_address + DMA_CTL3_OFFSET),
+				  (DMA_MASK_MODE_BITS <<
+				   ((ch - 8) * DMA_SHIFT_MODE_BITS)));
+	}
+
+	/* Updating the enable variable. */
+	ioh_dma_channel_info[channel].bChEnabled = (u16) 0;
+
+	IOH_DEBUG("Function dma_disable_ch returns " "%d.\n", IOH_DMA_SUCCESS);
+	return IOH_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 ioh_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 IOH_DMA_SUCCESS
+
+	@see
+			- ioh_set_dma_count
+ */
+int dma_set_count(int channel, u32 count)
+{
+	ioh_dma_channel_info[channel].DMATransferSize = count;
+
+	IOH_DEBUG("Function dma_set_count returns %d.\n", IOH_DMA_SUCCESS);
+	return IOH_DMA_SUCCESS;
+}
+
+/*! @ingroup	HALLayerAPI
+	@fn		int dma_add_desc(int channel,
+				struct ioh_dma_desc *start,
+				struct ioh_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 ioh_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
+				ioh_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 IOH_DMA_SUCCESS	--> If appending of the
+			descriptor is successful.
+
+	@see
+		- ioh_add_dma_desc
+*/
+int dma_add_desc(int channel, struct ioh_dma_desc *start,
+		 struct ioh_dma_desc *end)
+{
+	struct ioh_dma_desc *desc_addr;
+
+	desc_addr = ioh_dma_channel_info[channel].pTailOfList;
+
+	/* Obtaining the virtual address. */
+	desc_addr = (struct ioh_dma_desc *) phys_to_virt((u32) desc_addr);
+
+	/* If virtual address calculation successful. */
+	desc_addr->nextDesc = (u32) start;
+	ioh_dma_channel_info[channel].pTailOfList = end;
+
+	IOH_DEBUG("Function dma_add_desc returns %d.\n", IOH_DMA_SUCCESS);
+	return IOH_DMA_SUCCESS;
+}
+
+/*! @ingroup	HALLayerAPI
+	@fn	void  dma_set_callback (int channel,  void (*ioh_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 ioh_dma_channel_info with the
+				parameter passed.
+
+	@param		channel		[@ref IN]	Channel number.
+	@param		ioh_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
+		- ioh_dma_set_callback
+  */
+void dma_set_callback(int channel,
+		      void (*ioh_dma_cbr) (int value, unsigned long data1),
+		      unsigned long data)
+{
+	ioh_dma_channel_info[channel].call_back_func_ptr = ioh_dma_cbr;
+	ioh_dma_channel_info[channel].callback_data = data;
+
+	IOH_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
+				IOH_DMA_END, denoting that the DMA transmission
+				has end.
+				- If a DMA abort interrupt has occurred, then
+				invoke the callback function with @ref
+				IOH_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 ioh_dma_devices *) dev_id)->base_addr;
+	dev_type = ((struct ioh_dma_devices *) dev_id)->dev_typ;
+
+	/* Reading the status registers. */
+	status_reg0 = IOH_READ_LONG((base_address + DMA_STS0_OFFSET));
+	status_reg2 = IOH_READ_LONG((base_address + DMA_STS2_OFFSET));
+	IOH_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 < IOH_DMA_CHANNELS_MAX; i++) {
+		if ((ioh_dma_channel_table[i].dma_dev_id == dev_type) &&
+		    (ioh_dma_channel_table[i].ch_alloced == 1) &&
+		    (ioh_dma_channel_info[i].bChEnabled == 1)
+		    ) {
+			status =
+			    dma_get_interrupt_status(ioh_dma_channel_table
+						     [i].channel, status_reg0,
+						     status_reg2);
+			IOH_DEBUG
+			    ("dma_interrupt -> Interrupt status for ch: %d is "
+			    "%x.\n", i, status);
+
+			if (status == 1) {
+				int value = IOH_DMA_END;
+
+				status =
+				    dma_get_abort_status(ioh_dma_channel_table
+							 [i].channel,
+							 status_reg0,
+							 status_reg2);
+
+				if (status == 1) {
+					value = IOH_DMA_ABORT;
+
+					IOH_DEBUG
+					    ("dma_interrupt -> DMA Abort "
+					    "interrupt from channel%d.\n", i);
+				}
+#ifdef DEBUG
+				else {
+					IOH_DEBUG
+					    ("dma_interrupt -> DMA Completion "
+					    "interrupt "
+					     "from channel%d.\n", i);
+				}
+#endif
+				if (ioh_dma_channel_info[i].
+				    call_back_func_ptr) {
+					u32 data =
+					    ioh_dma_channel_info
+					    [i].callback_data;
+					(ioh_dma_channel_info
+					 [i].call_back_func_ptr) (value, data);
+				}
+
+				/* Determining whether the channel has been
+				disabled. */
+				{
+					u32 ctrl_val;
+					s32 ch =
+					    ioh_dma_channel_table[i].channel;
+					u32 base_address =
+					    ioh_dma_channel_table[i].base;
+
+					if (ch < 8) {
+						ctrl_val =
+						    IOH_READ_LONG((base_address
+							    + DMA_CTL0_OFFSET));
+
+						ctrl_val &=
+						    ((0x3) <<
+						    (ch * DMA_SHIFT_MODE_BITS));
+					} else {
+						ctrl_val =
+						    IOH_READ_LONG((base_address
+							    + DMA_CTL3_OFFSET));
+						ctrl_val &=
+						    ((0x3) <<
+						     ((ch - 8) *
+						      DMA_SHIFT_MODE_BITS));
+					}
+
+					ioh_dma_channel_info[i].bChEnabled =
+					    (ctrl_val != 0) ? 1 : 0;
+
+				}	/* End */
+
+				retval = IRQ_HANDLED;
+			}
+		}
+	}
+
+	IOH_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 IOH_DMA_SUCCESS	--> On Success.
+
+	@see
+			- ioh_dma_direct_start
+ */
+int dma_direct_start(int channel)
+{
+	int ch;
+	u32 base_address;
+
+	ch = ioh_dma_channel_table[channel].channel;
+	base_address = ioh_dma_channel_table[channel].base;
+
+	if (ch < 8) {
+		IOH_DMA_BIT_SET((base_address + DMA_CTL2_OFFSET),
+				(DMA_DIR_START << ch));
+	} else {
+		IOH_DMA_BIT_SET((base_address + DMA_CTL2_OFFSET),
+				(DMA_DIR_START << (ch + 6)));
+	}
+
+	IOH_DEBUG("dma_direct_start -> Direct2 RegValue: "
+		  "%x.\n", IOH_READ_LONG((base_address + DMA_CTL2_OFFSET)));
+
+	IOH_DEBUG("Function dma_direct_start returns "
+		  "%d.\n", IOH_DMA_SUCCESS);
+	return IOH_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 IOH_DMA_SUCCESS	--> On Success.
+
+	@see
+			- ioh_set_dma_priority
+  */
+int dma_set_priority(int channel, int priority)
+{
+	int ch;
+	u32 base_address;
+	u32 reg_val;
+
+	ch = ioh_dma_channel_table[channel].channel;
+	base_address = ioh_dma_channel_table[channel].base;
+
+	reg_val = IOH_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));
+	}
+
+	IOH_WRITE_LONG(reg_val, (base_address + DMA_CTL1_OFFSET));
+
+	IOH_DEBUG("Function dma_set_priority returns "
+		  "%d.\n", IOH_DMA_SUCCESS);
+	return IOH_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 IOH_DMA_SUCCESS	--> On Success.
+
+	@see
+		- dma_init
+		- dma_exit
+  */
+int dma_enable_disable_interrupt(int channel, int bEnable)
+{
+	u32 base_address;
+	u16 ch;
+
+	ch = ioh_dma_channel_table[channel].channel;
+	base_address = ioh_dma_channel_table[channel].base;
+
+	if (ch < 8) {
+		if (IOH_DMA_INTERRUPT_ENABLE == bEnable) {
+			IOH_DMA_BIT_SET((base_address + DMA_CTL2_OFFSET),
+					(DMA_INTERRUPT_BIT << ch));
+		} else {	/* if(bEnable == IOH_DMA_INTERRUPT_DISABLE) */
+
+			IOH_DMA_BIT_CLEAR((base_address + DMA_CTL2_OFFSET),
+					  (DMA_INTERRUPT_BIT << ch));
+		}
+
+	} else {
+		if (IOH_DMA_INTERRUPT_ENABLE == bEnable) {
+			IOH_DMA_BIT_SET((base_address + DMA_CTL2_OFFSET),
+					(DMA_INTERRUPT_BIT << (ch + 8)));
+		} else {	/* if(bEnable == IOH_DMA_INTERRUPT_DISABLE) */
+
+			IOH_DMA_BIT_CLEAR((base_address + DMA_CTL2_OFFSET),
+					  (DMA_INTERRUPT_BIT << (ch + 8)));
+		}
+	}
+
+	IOH_DEBUG("dma_enable_disable_interrupt -> CTL2 Register Value: "
+		  "%x.\n", IOH_READ_LONG((base_address + DMA_CTL2_OFFSET)));
+
+	IOH_DEBUG("Function dma_enable_disable_interrupt returns "
+		  "%d.\n", IOH_DMA_SUCCESS);
+	return IOH_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
+		- ioh_set_dma_mode
+		- ioh_set_dma_addr
+		- ioh_set_dma_count
+		- ioh_set_dma_desc
+		- ioh_add_dma_desc
+		- ioh_enable_dma
+		- ioh_disable_dma
+		- ioh_set_dma_priority
+		- ioh_dma_direct_start
+
+  */
+
+void get_dma_status(int channel, u16 *pDMAStatus)
+{
+	u32 status_val;
+	u32 base_address;
+	u16 ch;
+
+	ch = ioh_dma_channel_table[channel].channel;
+	base_address = ioh_dma_channel_table[channel].base;
+
+	if (ch < 8) {
+		status_val = IOH_READ_LONG(base_address + DMA_STS0_OFFSET);
+		*pDMAStatus = (u16) ((status_val >> (DMA_SHIFT_STATUS_BITS +
+						     (ch *
+						      DMA_SIZE_STATUS_BITS))) &
+				     (DMA_MASK_STATUS_BITS));
+	} else {
+		status_val = IOH_READ_LONG(base_address + DMA_STS2_OFFSET);
+		*pDMAStatus = (u16) ((status_val >> (DMA_SHIFT_STATUS_BITS +
+						     ((ch -
+						       8) *
+						      DMA_SIZE_STATUS_BITS))) &
+				     (DMA_MASK_STATUS_BITS));
+	}
+
+	IOH_DEBUG("Function get_dma_status invoked successfully.\n");
+}
+
+/*!	@ingroup	HALLayerAPI
+	@fn		int dma_set_desc(int channel,
+				struct ioh_dma_desc *start,
+				struct ioh_dma_desc *end)
+	@brief		Sets descriptors .
+	@remarks	This functions sets the descriptor settings for
+				SCATTER GATHER mode. It does not perform any
+				register settings, instead retains the data for
+				further use. The main tasks performed by this
+				function are:
+				- Sets the pHeadOfList field of the @ref
+				ioh_dma_channel_info structure to the value of
+				the argument start.
+				- Set the pTailOfList field of the @ref
+				ioh_dma_channel_info structure to the value of
+				the argument end.
+
+	@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.
+
+	@see
+			- ioh_set_dma_desc
+ */
+
+int dma_set_desc(int channel, struct ioh_dma_desc *start,
+		 struct ioh_dma_desc *end)
+{
+	ioh_dma_channel_info[channel].pHeadOfList = start;
+	ioh_dma_channel_info[channel].pTailOfList = end;
+
+	IOH_DEBUG("Function dma_set_desc returns %d.\n", IOH_DMA_SUCCESS);
+	return IOH_DMA_SUCCESS;
+}
+
+/*!	@ingroup	InternalFunction
+	@fn			void get_free_ch(int index)
+	@brief		Get a free channel info entry and populate the entry.
+	@remarks	Reset all the entries within the array
+				ioh_dma_channel_info[index]
+
+	@param		index	[@ref IN]	Index in the
+					ioh_dma_channel_table
+
+	@return	None
+
+	@see
+			- dma_request_ch
+ */
+void get_free_ch(int index)
+{
+	memset((void *)&ioh_dma_channel_info[index], 0,
+	       sizeof(struct ioh_dma_controller_info));
+	IOH_DEBUG("Function get_free_ch invoked successfully.\n");
+}
+
+/*! @ingroup	HALLayerAPI
+	@fn			int dma_request_ch(u32 req_dev_id, int dreq)
+	@brief		Reserves a channel based on request.
+	@remarks	This function is invoked when a kernel module requests
+				to reserve a DMA channel. The main tasks
+				performed by this function are:
+				- Checks the @ref ioh_dma_channel_table for a
+				matching entry corresponding to the dev_id of
+				the requesting device and dreq signal.
+				- If there is a matching entry, checks if this
+				channel is already allocated.
+				- If no invoke get_free_ch to reset the entries
+				for the corresponding channel and return the
+				entry index.
+				- If no matching entry is found return -EBUSY.
+
+	@param		req_dev_id	[@ref IN]	Device id of the device
+							that requests DMA  .
+	@param		dreq	[@ref IN]	DMA request signal number.
+
+	@return		int
+			- DMA channel number (>=0)	--> On Success.
+			- -EBUSY	--> DMA channel cannot be allocated..
+
+	@see
+			- ioh_request_dma
+ */
+
+int dma_request_ch(u32 req_dev_id, int dreq)
+{
+	int retval;
+	int i;
+
+	for (i = 0; i < IOH_DMA_CHANNELS_MAX; i++) {
+		if ((ioh_dma_channel_table[i].req_device_id == req_dev_id) &&
+		    (ioh_dma_channel_table[i].request_signal == dreq)) {
+			if ((1 == ioh_dma_channel_table[i].ch_found) &&
+			    (0 == ioh_dma_channel_table[i].ch_alloced)) {
+				get_free_ch(i);
+				IOH_DEBUG
+				    ("dma_request_ch -> Function get_free_ch "
+				     "invoked successfully.\n");
+				ioh_dma_channel_table[i].ch_alloced = 1;
+				retval = i;
+
+				break;
+			}
+		}
+	}
+
+	if (IOH_DMA_CHANNELS_MAX == i) {
+		retval = -EBUSY;
+		IOH_LOG(KERN_ERR, "dma_request_ch ->  Not able to allocate "
+			"channel.\n");
+	}
+
+	IOH_DEBUG("Function dma_request_ch returns %d.\n", retval);
+	return retval;
+}
+
+/*!	@ingroup	HALLayerAPI
+	@fn			int dma_free_ch(int channel)
+	@brief		Frees the requested channel.
+	@remarks	This function is invoked when a kernel
+				module requests to free a DMA channel. The main
+				tasks performed by this function are:
+				- If the channel is already free return
+					IOH_DMA_SUCCESS.
+				- Else disable the channel by invoking
+				@ref dma_disable_ch API.
+				- Disable the channel interrupt by invoking
+				@ref dma_enable_disable_interrupt
+				- Mark the channel as free in the structures
+				@ref ioh_dma_channel_info and @ref
+				ioh_dma_channel_table and return @ref
+				IOH_DMA_SUCCESS.
+
+	@param		channel	[@ref IN]	DMA channel number to be freed.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+
+	@see
+			- ioh_free_dma
+ */
+
+int dma_free_ch(int channel)
+{
+	int retval;
+
+	if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_DEBUG("dma_free_ch -> Channel is already free\n");
+		retval = IOH_DMA_SUCCESS;
+	} else {
+		/* To stop any active transfer on DMA, disable DMA */
+		(void)dma_disable_ch(channel);
+		IOH_DEBUG("dma_free_ch -> Function dma_disable_ch invoked "
+			  "successfully.\n");
+
+		(void)dma_enable_disable_interrupt(channel,
+						   IOH_DMA_INTERRUPT_DISABLE);
+		IOH_DEBUG
+		    ("dma_free_ch -> Function dma_enable_disable_interrupt "
+		     "invoked successfully.\n");
+
+		ioh_dma_channel_table[channel].ch_alloced = 0;
+
+		retval = IOH_DMA_SUCCESS;
+	}
+
+	IOH_DEBUG("Function dma_free_ch returns %d.\n", IOH_DMA_SUCCESS);
+	return retval;
+}
--- /dev/null
+++ b/drivers/dma/pch_dma/pch_dma_hal.h
@@ -0,0 +1,594 @@
+/**
+ * @file ioh_dma_hal.h
+ *
+ * @brief
+ *		This file declares the structures & data types used by the HAL
+ *		functions of IOH_DMA_CONTROLLER driver.
+ *
+ * @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.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 08/14/2009
+ *
+ */
+
+#ifndef __IOH_DMA_HAL_H__
+#define __IOH_DMA_HAL_H__
+
+#include <linux/interrupt.h>
+#include "pch_dma_main.h"
+
+/*!
+	@defgroup	DMA
+*/
+
+/*!	@defgroup	Global
+	@ingroup	DMA
+	@brief		This group contains all the global data
+				structures used by the DMA module.
+*/
+
+/*!	defgroup	InternalFunction
+	@ingroup	DMA
+	@brief		This group contains all the function which
+				are used by other APIs for performing some
+				small tasks for facilitating the logic
+				of the driver.
+*/
+
+/*!	@defgroup	PCILayer
+	@ingroup	DMA
+	@brief		This group contains all the utilities
+				used to interface the DMA module with
+				the PCI subsystem of the Kernel.
+*/
+
+/*!	@defgroup	InterfaceLayer
+	@ingroup	DMA
+	@brief		This group contains all the utilities
+				used by the DMA module to interface with
+				the other modules.
+*/
+
+/*!	@defgroup	HALLayer
+	@ingroup	DMA
+	@brief		This group contains all the utilities
+				used to DMA module to interact with the
+				hardware.
+*/
+
+/*!	@defgroup	PCILayerAPI
+	@ingroup	PCILayer
+	@brief		This group contains the APIs used to
+				interface the DMA module with the PCI
+				subsystem of the Kernel.
+*/
+
+/*!	@defgroup	PCILayerFacilitators
+	@ingroup	PCILayer
+	@brief		This group contains the data structures
+				used by the PCILayerAPIs for their
+				functioning.
+*/
+
+/*!	@defgroup	HALLayerAPI
+	@ingroup	HALLayer
+	@brief		This group contains the APIs used to
+				communicate with the hardware.
+*/
+
+/*!	@defgroup	HALLayerFacilitators
+	@ingroup	HALLayer
+	@brief		This group contains the data structures
+				used to communicate with the hardware.
+*/
+
+/*!	@defgroup	InterfaceLayerAPI
+	@ingroup	InterfaceLayer
+	@brief		This group contains the APIs used by the
+				DMA module to interface with other modules.
+*/
+
+/*!	@defgroup	InterfaceLayerFacilitators
+	@ingroup	InterfaceLayer
+	@brief		This group contains the data structures
+				used by the DMA module to interface with
+				other modules.
+*/
+
+/*** Device specific limitations and properties. ***/
+
+/*!	@ingroup	DMA
+	@def		IOH_DMA_CHANNELS_MAX
+	@brief		The maximum number of channels allowed
+				in any of the IOH device.
+*/
+#define IOH_DMA_CHANNELS_MAX				(64)
+
+/*!	@ingroup	DMA
+	@def		IOH_DMA_MAX_DEVS
+	@brief		The no. of DMA devices allowable.
+
+	@see
+		- ioh_dma_devices
+*/
+#define IOH_DMA_MAX_DEVS					(4)
+
+/*!	@ingroup	DMA
+	@def		IOH_DMA_8BIT_SIZE_MAX
+	@brief		The maximum number of transfer size in
+				bytes for a channel if access size is set
+				to 8BIT.
+*/
+#define IOH_DMA_8BIT_SIZE_MAX			(2047)
+
+/*!	@ingroup	DMA
+	@def		IOH_DMA_16BIT_SIZE_MAX
+	@brief		The maximum number of transfer size in
+				bytes for a channel if access size is set
+				to 16BIT.
+*/
+#define IOH_DMA_16BIT_SIZE_MAX			(4094)
+
+/*!	@ingroup	DMA
+	@def		IOH_DMA_32BIT_SIZE_MAX
+	@brief		The maximum number of transfer size in
+				bytes for a channel if access size is set
+				to 32BIT.
+*/
+#define IOH_DMA_32BIT_SIZE_MAX			(4096)
+
+/********/
+
+/*** Device IDs of DMA requesting devices. ***/
+/*!	@ingroup	DMA
+	@def		PCI_DEVICE_ID_IOH_UART0
+	@brief		The deviceID of the IOH GE UART
+				device 0 which can use the DMA features.
+*/
+#define PCI_DEVICE_ID_IOH_UART0						(0x8811)
+
+/*!	@ingroup	DMA
+	@def		PCI_DEVICE_ID_IOH_UART1
+	@brief		The deviceID of the IOH GE UART
+				device 1 which can use the DMA features.
+*/
+#define PCI_DEVICE_ID_IOH_UART1						(0x8812)
+
+/*!	@ingroup	DMA
+	@def		PCI_DEVICE_ID_IOH_UART2
+	@brief		The deviceID of the IOH GE UART
+				device 2 which can use the DMA features.
+*/
+#define PCI_DEVICE_ID_IOH_UART2						(0x8813)
+
+/*!	@ingroup	DMA
+	@def		PCI_DEVICE_ID_IOH_UART3
+	@brief		The deviceID of the IOH GE UART
+				device 3 which can use the DMA features.
+*/
+#define PCI_DEVICE_ID_IOH_UART3						(0x8814)
+
+/*!	@ingroup	DMA
+	@def		PCI_DEVICE_ID_IOH_SPI
+	@brief		The deviceID of the IOH GE SPI
+				device which can use the DMA features.
+*/
+#define PCI_DEVICE_ID_IOH_SPI	(0x8816)
+
+/*** Internal device IDs used for identifing the DMAC . ***/
+/*!	@ingroup	Global
+	@def		IOH_DMA_4CH0
+	@brief		The device ID for the first DMA device
+				with 4 channels.
+*/
+#define IOH_DMA_4CH0						(0x40)
+
+/*!	@ingroup	Global
+	@def		IOH_DMA_4CH1
+	@brief		The device ID for the second DMA device
+				with 4 channels.
+*/
+#define IOH_DMA_4CH1						(0x41)
+
+/*!	@ingroup	Global
+	@def		IOH_DMA_4CH2
+	@brief		The device ID for the third DMA device
+				with 4 channels.
+*/
+#define IOH_DMA_4CH2						(0x42)
+
+/*!	@ingroup	Global
+	@def		IOH_DMA_4CH3
+	@brief		The device ID for the fourth DMA device
+				with 4 channels.
+*/
+#define IOH_DMA_4CH3						(0x43)
+
+/*!	@ingroup	Global
+	@def		IOH_DMA_4CH4
+	@brief		The device ID for the fifth DMA device
+				with 4 channels.
+*/
+#define IOH_DMA_4CH4						(0x44)
+
+/*!	@ingroup	Global
+	@def		IOH_DMA_8CH0
+	@brief		The device ID for the first DMA device
+				with 8 channels.
+*/
+#define IOH_DMA_8CH0						(0x80)
+
+/*!	@ingroup	Global
+	@def		IOH_DMA_8CH1
+	@brief		The device ID for the second DMA device
+				with 8 channels.
+*/
+#define IOH_DMA_8CH1						(0x81)
+
+/*!	@ingroup	Global
+	@def		IOH_DMA_8CH2
+	@brief		The device ID for the third DMA device
+				with 8 channels.
+*/
+#define IOH_DMA_8CH2						(0x82)
+
+/*!	@ingroup	Global
+	@def		IOH_DMA_8CH3
+	@brief		The device ID for the fourth DMA device
+				with 8 channels.
+*/
+#define IOH_DMA_8CH3						(0x83)
+
+/*!	@ingroup	Global
+	@def		IOH_DMA_12CH0
+	@brief		The device ID for the first DMA device
+				with 12 channels.
+*/
+#define IOH_DMA_12CH0						(0xC0)
+
+/******/
+
+/*** DMA Controller Register Offsets. ***/
+
+/*!	@ingroup	HALLayer
+	@def		DMA_CTL0_OFFSET
+	@brief		DMA Control register 0 offset.
+*/
+#define DMA_CTL0_OFFSET					(0x00UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_CTL1_OFFSET
+	@brief		DMA Control register 1 offset.
+*/
+#define DMA_CTL1_OFFSET						(0x04UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_CTL2_OFFSET
+	@brief		DMA Control register 2 offset.
+*/
+#define DMA_CTL2_OFFSET						(0x08UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_CTL3_OFFSET
+	@brief		DMA Control register 3 offset.
+*/
+#define DMA_CTL3_OFFSET						(0x0CUL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_STS0_OFFSET
+	@brief		DMA Status register 0 offset.
+*/
+#define DMA_STS0_OFFSET						(0x10UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_STS1_OFFSET
+	@brief		DMA Status register 1 offset.
+*/
+#define DMA_STS1_OFFSET						(0x14UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_STS2_OFFSET
+	@brief		DMA Status register 2 offset.
+*/
+#define DMA_STS2_OFFSET						(0x18UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_IN_AD_OFFSET
+	@brief		DMA IN Address register offset.
+*/
+#define DMA_IN_AD_OFFSET					(0x20UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_OUT_AD_OFFSET
+	@brief		DMA Out Address register offset.
+*/
+#define DMA_OUT_AD_OFFSET					(0x24UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_SZ_OFFSET
+	@brief		DMA Size register offset.
+*/
+#define DMA_SZ_OFFSET						(0x28UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_NX_AD_OFFSET
+	@brief		DMA Next Address register offset.
+*/
+#define DMA_NX_AD_OFFSET					(0x2CUL)
+
+/**********/
+
+/*** Individual register bits. ***/
+
+/*!	@ingroup	HALLayer
+	@def		DMA_SIZE_TYPE_BITS
+	@brief		The DMA size bits.
+*/
+#define DMA_SIZE_TYPE_BITS					(0x00003000UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_SET_OR_CLEAR_DIR_BIT
+	@brief		Mask for direction bit.
+*/
+#define DMA_SET_OR_CLEAR_DIR_BIT			(0x00000004UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_MASK_MODE_BITS
+	@brief		Mask for mode bits.
+*/
+#define DMA_MASK_MODE_BITS					(0x00000003UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_SHIFT_MODE_BITS
+	@brief		DMA shift mode bits.
+*/
+#define DMA_SHIFT_MODE_BITS					(4)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_MASK_PRIORITY_BITS
+	@brief		Mask for priority bits.
+*/
+#define DMA_MASK_PRIORITY_BITS				(0x3UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_SHIFT_PRIORITY_BITS
+	@brief		Shift value for DMA priority bits.
+*/
+#define DMA_SHIFT_PRIORITY_BITS				(4)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_SHIFT_SIZE_TYPE_BITS
+	@brief		Shift value for the DMA size bit.
+*/
+#define DMA_SHIFT_SIZE_TYPE_BITS			(12)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_DIR_START
+	@brief		Direct Start Bit Setting values.
+*/
+#define DMA_DIR_START						(0x00000100UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_INTERRUPT_BIT
+	@brief		Interrupt Enable Bit setting values.
+*/
+#define DMA_INTERRUPT_BIT					(0x00000001UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_ABORT_OCCUR
+	@brief		Abort notify Bit Setting Values
+*/
+#define DMA_ABORT_OCCUR						(0x00000100UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_INTERRUPT_OCCUR
+	@brief		Interrupt notify Bit Setting Values
+*/
+#define DMA_INTERRUPT_OCCUR					(0x00000001UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_MASK_STATUS_BITS
+	@brief		Mask for status bits.
+*/
+#define DMA_MASK_STATUS_BITS				(0x3UL)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_SIZE_STATUS_BITS
+	@brief		The DMA size status bits.
+*/
+#define DMA_SIZE_STATUS_BITS				(2)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_SHIFT_STATUS_BITS
+	@brief		The shift value for DMA status bits.
+*/
+#define DMA_SHIFT_STATUS_BITS				(16)
+
+/*********/
+
+/*** Status denoting macros. ***/
+
+/*!	@ingroup	HALLayer
+	@def		DMA_STATUS_IDLE
+	@brief		Constant used to denote the transfer status as IDLE.
+	@note		This constant is used by DMA modules to make the
+				other module aware of the DMA status.
+*/
+#define DMA_STATUS_IDLE						(0)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_STATUS_DESC_READ
+	@brief		Constant used to denote the transfer status as
+				DESCRIPTOR_READ.
+	@note		This constant is used by DMA modules to make the
+				other module aware of the DMA status.
+*/
+#define DMA_STATUS_DESC_READ				(1)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_STATUS_WAIT
+	@brief		Constant used to denote the transfer status as WAIT.
+	@note		This constant is used by DMA modules to make the
+				other module aware of the DMA status.
+*/
+#define DMA_STATUS_WAIT						(2)
+
+/*!	@ingroup	HALLayer
+	@def		DMA_STATUS_ACCESS
+	@brief		Constant used to denote the transfer status as ACCESS
+	@note		This constant is used by DMA modules to make the
+				other module aware of the DMA status.
+*/
+#define DMA_STATUS_ACCESS					(3)
+
+/*!	@ingroup	HALLayer
+	@def		IOH_DMA_INTERRUPT_DISABLE
+	@brief		Constant used to denote disable interrupt.
+*/
+#define IOH_DMA_INTERRUPT_DISABLE			(0)
+
+/*!	@ingroup	HALLayer
+	@def		IOH_DMA_INTERRUPT_ENABLE
+	@brief		Constant used to denote enable interrupt.
+*/
+#define IOH_DMA_INTERRUPT_ENABLE			(1)
+
+/************/
+
+/*** Other Macros. ***/
+
+/*!	@ingroup	HALLayer
+	@def		COUNTER_LIMIT
+	@brief		The counter limit.
+*/
+#define COUNTER_LIMIT						(0xFFFF)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_ALL_THREE
+	@brief		Value used for masking the 3 LSB bits.
+*/
+#define MSK_ALL_THREE						(0x7)
+
+/*******/
+/*** Data Structures for stroing device specific information. ***/
+
+/*!	@ingroup	HALLayerFacilitators
+	@struct		__ioh_dma_devices
+	@brief		Format for maintaining the device information.
+	@note		This structure is used by the DMA module to retain
+				the information about the device.
+
+	@see
+		- ioh_dma_devices
+*/
+
+struct ioh_dma_devices {
+	u32 base_addr;		/**< The remapped base address.	*/
+	u32 dev_typ;		/**< The device type indicating number of DMA
+				channels */
+	void *dev;		/**< The void pointer for storing any references
+				if required */
+};
+
+/*!	@ingroup	HALLayerFacilitators
+		@struct		__ioh_dma_controller_info_t
+		@brief		Format for storing the details of the
+					DMA channels.
+*/
+
+struct ioh_dma_controller_info {
+	u16 DMATransferMode;		/**< DMA Transfer Mode 	*/
+	u16 bChEnabled;			/**< To know if channel is enabled or
+					not */
+	struct ioh_dma_desc *pHeadOfList;	/**< Pointer to start
+						descriptor */
+	struct ioh_dma_desc *pTailOfList;	/**< Pointer to last
+						descriptor */
+	void (*call_back_func_ptr) (int, unsigned long);/**< Address of the call
+					back function that is to be called when
+					an interrupt occurs */
+	u32 callback_data;		/**< The data to passed to the callback
+					function during invocation */
+	u16 DMAAccessSize;		/**< To store the access size (8bit,
+					16bit or 32bit) */
+	u16 DMATransferSize;		/**< To store the value of Transfer
+					Size */
+	u16 DMATransferDirection;	/**< To store the Direction of Transfer
+					(IN to OUT or OUT to IN) */
+	u32 in_addr;			/**< The in_address */
+	u32 out_addr;			/**< The out_address */
+};
+
+/*!	@ingroup	HALLayerFacilitators
+		@struct		ioh_dma_channel_alloc_table
+		@brief		Format for storing the details of the
+					allocation details of the DMA channels.
+*/
+
+struct ioh_dma_channel_alloc_table {
+	u32 dma_dev_id;	/**< The DMA device ID. */
+	enum ioh_channel_request_id request_signal;	/**< The request type.*/
+	u32 req_device_id;	/**< The device ID of the requested device */
+	u16 channel;		/**< The channel number. */
+	u16 ch_found:1;		/**< The flag variable for channel in use */
+	u16 ch_alloced:1;	/**< The flag variable for channel allocate. */
+	u32 base;		/**< The base address of the DMA device. */
+};
+
+									/*****/
+
+extern struct ioh_dma_channel_alloc_table
+ ioh_dma_channel_table[IOH_DMA_CHANNELS_MAX];
+extern struct ioh_dma_controller_info
+ ioh_dma_channel_info[IOH_DMA_CHANNELS_MAX];
+
+void dma_init(u32 base, u32 dev_type);
+int dma_free_ch(int channel);
+int dma_request_ch(u32 req_dev_id, int dreq);
+int dma_set_mode(int channel, struct ioh_dma_mode_param stModeParam);
+int dma_set_addr(int channel, u32 iaddr, u32 oaddr);
+int dma_enable_ch(int channel);
+int dma_disable_ch(int channel);
+int dma_set_count(int channel, u32 count);
+int dma_add_desc(int channel, struct ioh_dma_desc *start,
+		 struct ioh_dma_desc *end);
+int dma_set_desc(int channel, struct ioh_dma_desc *start,
+		 struct ioh_dma_desc *end);
+void dma_set_callback(int channel,
+		      void (*ioh_dma_cbr) (int value, unsigned long data1),
+		      unsigned long data);
+irqreturn_t dma_interrupt(int irq, void *dev_id);
+int dma_set_priority(int channel, int priority);
+int dma_direct_start(int channel);
+int dma_enable_disable_interrupt(int channel, int bEnable);
+void dma_get_abort_status(int channel, u16 *pAbortStatus);
+void dma_get_interrupt_status(int channel, u16 *pInterruptStatus);
+void get_dma_status(int channel, u16 *pDMAStatus);
+void get_free_ch(int index);
+void dma_exit(u32 dev_type);
+
+#endif
--- /dev/null
+++ b/drivers/dma/pch_dma/pch_dma_main.c
@@ -0,0 +1,1026 @@
+/**
+ * @file ioh_dma_main.c
+ *
+ * @brief
+ * This file defines the methods of IOH_DMA driver.
+ *
+ *
+ * @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.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 08/14/2009
+ *
+ */
+
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+#include "pch_debug.h"
+#include "pch_dma_hal.h"
+#include "pch_dma_pci.h"
+
+
+/*!	@ingroup	InterfaceLayerAPI
+	@fn		int ioh_request_dma(struct pci_dev *pdev, int dreq)
+	@brief		Used to request a DMA channel.
+	@remarks	Requests to reserve a DMA channel that connects
+				to number 'dreq' (DMA request signal) of PCI
+				device 'pdev' to the appropriate DMA channel
+				allocated for it within the DMA Controller. This
+				function is called by functions from other
+				kernel modules. The tasks performed by this
+				function are:
+				- Verifies whether the obtained parameters are
+				valid,
+				if not suitable error status codes are returned
+				to the called function.
+				- If valid interacts with the HAL API and
+				returns the status code returned by the HAL API.
+
+	@note		This function is accessible by other kernel modules.
+
+	@param		dev	[@ref IN]	PCI device that requires the DMA
+									channel.
+	@param		dreq	[@ref IN]	DMA request signal number.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EAGAIN	--> Device is in suspend mode.
+			- -EINVAL	--> pdev does not have a DMA request
+						type or number 'dreq' or 'pdev'
+						is NULL.
+*/
+int ioh_request_dma(struct pci_dev *pdev, int dreq)
+{
+	int retval;
+
+	/* Attaining the lock.  */
+	spin_lock(&ioh_device_lock);
+
+	/* If device suspended. */
+	if (1 == ioh_device_suspended) {
+		IOH_LOG(KERN_ERR,
+			"ioh_request_dma -> Device is in suspend mode.\n");
+		retval = -EAGAIN;
+	}
+	/* Invalid device structure. */
+	else if (NULL == pdev) {
+		IOH_LOG(KERN_ERR,
+			"ioh_request_dma -> Obtained device structure "
+			"is NULL.\n");
+		retval = -EINVAL;
+	}
+	/* Invalid request signal. */
+	else if ((dreq < IOH_DMA_TX_DATA_REQ0) ||
+		 (dreq > IOH_DMA_RX_DATA_REQ5)) {
+		IOH_LOG(KERN_ERR,
+			"ioh_request_dma -> Invalid request signal.\n");
+		retval = -EINVAL;
+	} else {
+		/* Requesting for reserving a DMA channel. */
+		retval = dma_request_ch((u32) (pdev->device), dreq);
+		IOH_DEBUG("ioh_request_dma -> Function dma_request_ch returned "
+			  "%d.\n", retval);
+	}
+
+	/* Releasing the lock. */
+	spin_unlock(&ioh_device_lock);
+
+	IOH_DEBUG("Function ioh_request_dma returns %d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_request_dma);
+
+/*!	@ingroup	InterfaceLayerAPI
+	@fn			int ioh_free_dma(int channel)
+	@brief		Used to free a DMA channel.
+	@remarks	Frees the allocated DMA channel that is provided
+				as the argument to the function. This function
+				is called by the functions from other kernel
+				modules. The main tasks performed by this
+				function are:
+				- Verifies whether the obtained parameters are
+				valid, if not suitable error status codes are
+				returned to the called function.
+				- If valid interacts with the HAL API for
+				freeing the channel and returns the status code
+				returned by the HAL API.
+	@note		This function is accessible by other kernel
+				modules.
+
+	@param		channel	[@ref IN]	DMA channel number
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EAGAIN		--> Device is in suspend mode.
+			- -ENODEV		--> Specified DMA channel does
+							not exist.
+*/
+int ioh_free_dma(int channel)
+{
+	int retval;
+
+	if (1 == ioh_device_suspended) {
+		IOH_LOG(KERN_ERR,
+			"ioh_free_dma -> Device is in suspend mode.\n");
+		retval = -EAGAIN;
+	} else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_free_dma -> Invalid Channel number: "
+			"%d.\n", channel);
+		retval = -ENODEV;
+	} else {
+		retval = dma_free_ch(channel);
+		IOH_DEBUG("ioh_free_dma -> Function dma_free_ch "
+			  "returned %d.\n", retval);
+	}
+
+	IOH_DEBUG("Function ioh_free_dma returns %d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_free_dma);
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn		int ioh_set_dma_mode(int channel,struct
+				ioh_dma_mode_param stModeParam)
+	@brief		Used to set the mode of the DMA.
+	@remarks	Sets the mode of DMA transfer - One shot mode
+				or Scatter/gather mode. In addition to this,
+				the function also sets the direction of DMA
+				transfer and DMA Size type. This function is
+				called by functions from other kernel modules.
+				The main tasks performed by this function are:
+				- Verifies whether the obtained parameters are
+				valid, if not suitable error status codes are
+				returned to the called function.
+				- If valid interacts with the HAL API to set the
+				required settings and returns the status code
+				returned by the HAL API.
+
+	@note		This function is accessible by other kernel modules.
+
+	@param		channel		[@ref IN]	DMA channel number
+	@param		stModeParam	[@ref IN]	Contains info about
+						direction of DMA transfer, mode
+						and Size type
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EAGAIN		--> The device is in suspend
+							mode.
+			- -ENODEV		--> Specified DMA channel does
+							not exist.
+			- -EINVAL		--> Parameter passed is invalid.
+			- -EBUSY		--> DMA channel is already
+							enabled.
+*/
+int ioh_set_dma_mode(int channel, struct ioh_dma_mode_param stModeParam)
+{
+	int retval;
+
+	/* Checking if device suspended.                                */
+	if (1 == ioh_device_suspended) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_mode -> Device is in suspend mode.\n");
+		retval = -EAGAIN;
+	}
+	/* Checking for validity of channel number.     */
+	else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_mode -> Invalid Channel number : " "%d.\n",
+			channel);
+		retval = -ENODEV;
+	}
+	/* Checking whether channel not allocated.              */
+	else if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_mode -> Channel not allocated.\n");
+		retval = -EINVAL;
+	}
+	/* Checking if channel already enabled.                 */
+	else if (ioh_dma_channel_info[channel].bChEnabled == 1) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_mode -> Channel already enabled.\n");
+		retval = -EBUSY;
+	}
+	/* Checking for validity of DMA Transfer MODE.  */
+	else if ((stModeParam.DMATransferMode != (u16) DMA_ONE_SHOT_MODE) &&
+		 (stModeParam.DMATransferMode !=
+		  (u16) DMA_SCATTER_GATHER_MODE)) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_mode -> Invalid DMA Transfer mode.\n");
+		retval = -EINVAL;
+	}
+	/* Checking for validity of Transfer Direction. */
+	else if ((stModeParam.TransferDirection != (u16) IOH_DMA_DIR_OUT_TO_IN)
+		 && (stModeParam.TransferDirection !=
+		     (u16) IOH_DMA_DIR_IN_TO_OUT)) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_mode -> Invalid DMA Transfer Direction." \
+			"\n");
+		retval = -EINVAL;
+	}
+	/* Checking for validity of Transfer Size Type. */
+	else if ((stModeParam.DMASizeType != (u16) IOH_DMA_SIZE_TYPE_8BIT) &&
+		 (stModeParam.DMASizeType != (u16) IOH_DMA_SIZE_TYPE_16BIT) &&
+		 (stModeParam.DMASizeType != (u16) IOH_DMA_SIZE_TYPE_32BIT)) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_mode -> Invalid DMA Size Type.\n");
+		retval = -EINVAL;
+	} else {
+		/* Setting the required DMA mode. */
+		retval = dma_set_mode(channel, stModeParam);
+		IOH_DEBUG("ioh_set_dma_mode -> Function dma_set_mode "
+			  "returned %d.\n", retval);
+	}
+
+	IOH_DEBUG("Function ioh_set_dma_mode returns %d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_set_dma_mode);
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn		int ioh_set_dma_addr(int channel, unsigned int iaddr,
+				unsigned int oaddr)
+	@brief		Used to set the in and out address of the DMA channel.
+	@remarks	Sets the address of the inside bridge and the outside
+				bridge for the 'One Shot Mode' of DMA Transfer.
+				This function is invoked by functions from other
+				modules. The main tasks performed by this
+				function are:
+				- Verifies whether the obtained parameters are
+				valid, if not suitable error status codes are
+				returned to the called function.
+				- If valid interacts with the HAL API to set the
+				inside and outside address and returns the
+				status code returned by the HAL API.
+	@note		This function is accessible by other kernel modules. The
+				following points has to be noted while passing
+				the in-address and out-address paramter.
+				- The address passed should be valid physical
+				address within the memory space.
+				- It should not be a configuration space or IO
+				space address.
+				- If the transfer is for large data, the address
+				should point to contagious alligned memory space
+				.
+
+	@param	channel		[@ref IN]	DMA channel number .
+	@param	iaddr		[@ref IN]	Address of inside bridge.
+	@param	oaddr		[@ref IN]	Address of outside bridge.
+
+	@return int
+		- @ref IOH_DMA_SUCCESS	--> On success.
+		- -EAGAIN	--> The device is in suspend mode.
+		- -ENODEV	--> Specified DMA channel does not exist.
+		- -EINVAL	--> Parameter passed is invalid.
+		- -EBUSY	--> DMA transfer in progress or channel is
+					already enabled.
+
+*/
+int ioh_set_dma_addr(int channel, unsigned int iaddr, unsigned int oaddr)
+{
+	int retval;
+
+	/* If the device is in suspend mode. */
+	if (1 == ioh_device_suspended) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_addr -> Device is in suspend mode.\n");
+		retval = -EAGAIN;
+	}
+	/* Checking for validity of channel number  */
+	else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_addr -> Invalid Channel "
+			"number: %d.\n", channel);
+		retval = -ENODEV;
+	}
+	/* Checking whether channel is not allocated. */
+	else if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_addr -> Channel not "
+			"allocated.\n");
+		retval = -EINVAL;
+	}
+	/* Checking whether the channel is already enabled. */
+	else if (ioh_dma_channel_info[channel].bChEnabled == 1) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_addr -> Channel already "
+			"enabled.\n");
+		retval = -EBUSY;
+	}
+	/*Checking if addresses specified are NULL or not */
+	else if ((iaddr == 0) || (oaddr == 0)) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_addr -> Invalid address.\n");
+		retval = -EINVAL;
+	}
+	/* Checking if the mode of transfer is  other than ONE_SHOT. */
+	else if (ioh_dma_channel_info[channel].DMATransferMode !=
+		 (u16) DMA_ONE_SHOT_MODE) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_addr -> Current Mode is "
+			"not DMA_ONE_SHOT_MODE.\n");
+		retval = -EINVAL;
+	} else {
+		/* setting the in and out address. */
+		retval = dma_set_addr(channel, iaddr, oaddr);
+		IOH_DEBUG("ioh_set_dma_addr -> Function dma_set_addr invoked "
+			  "successfully returned %d.\n", retval);
+	}
+
+	IOH_DEBUG("Function ioh_set_dma_addr returns %d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_set_dma_addr);
+
+/*!	@ingroup	InterfaceLayerAPI
+	@fn		int ioh_set_dma_count(int channel, unsigned int count)
+	@brief		Used to set the DMA transfer count for a DMA channel.
+	@remarks	Sets the value of DMA transfer count. This function
+				sets the count value only for the 'One Shot
+				Mode' of DMA Transfer. This function is invoked
+				by functions from other modules. The main tasks
+				performed by this function are:
+				- Verifies whether the obtained parameters are
+				valid, if not suitable error status codes are
+				returned to the called function.
+				- If valid interacts with the HAL API to set the
+				access count settings and returns the status
+				code returned by the HAL API.
+	@note		This function is accessible by other kernel modules.
+
+	@param		channel	[@ref IN]	DMA channel number.
+	@param		count	[@ref IN]	The number of bytes to transfer.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EAGAIN	--> The device is in suspend mode.
+			- -ENODEV	--> Specified DMA channel does not
+						exist.
+			- -EBUSY	--> DMA transfer in progress or channel
+						is already enabled.
+			- -EINVAL	--> Parameter passed is invalid.
+
+ */
+int ioh_set_dma_count(int channel, unsigned int count)
+{
+	int retval = IOH_DMA_SUCCESS;
+
+	/* Checking if the device is in suspend mode. */
+	if (1 == ioh_device_suspended) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_count -> The device is in "
+			"suspend mode.");
+		retval = -EAGAIN;
+	}
+	/* Checking for validity of channel number.  */
+	else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_count -> Invalid Channel "
+			"number : %d.\n", channel);
+		retval = -ENODEV;
+	}
+	/* Checking whether channel is not allocated. */
+	else if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_count -> Channel is not "
+			"allocated.\n");
+		retval = -EINVAL;
+	}
+	/* Checking whether the channel is enabled. */
+	else if (ioh_dma_channel_info[channel].bChEnabled == 1) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_count -> Channel already "
+			"enabled.\n");
+		retval = -EBUSY;
+	}
+	/* Checking if the mode of transfer is other than ONE_SHOT. */
+	else if (ioh_dma_channel_info[channel].DMATransferMode !=
+		 (u16) DMA_ONE_SHOT_MODE) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_count -> Current Mode is "
+			"not DMA_ONE_SHOT_MODE.\n");
+		retval = -EINVAL;
+	}
+	/* Checking the limits of count value. */
+	else {
+		unsigned int max_count;
+
+		switch (ioh_dma_channel_info[channel].DMAAccessSize) {
+		case IOH_DMA_SIZE_TYPE_8BIT:
+			max_count = IOH_DMA_8BIT_COUNT_MAX;
+			break;
+
+		case IOH_DMA_SIZE_TYPE_16BIT:
+			max_count = IOH_DMA_16BIT_COUNT_MAX;
+			break;
+
+		case IOH_DMA_SIZE_TYPE_32BIT:
+			max_count = IOH_DMA_32BIT_COUNT_MAX;
+			break;
+
+		default:
+			IOH_LOG(KERN_ERR, "ioh_set_dma_count -> Invalid Access "
+				"Size.\n");
+			max_count = 0;
+			retval = -EINVAL;
+			break;
+		}
+
+		if ((retval == IOH_DMA_SUCCESS) && (count > max_count)) {
+			IOH_LOG(KERN_ERR,
+				"ioh_set_dma_count -> Count (%d) exceeds "
+				"limit the maximum expected count (%d).\n",
+				count, max_count);
+			retval = -EINVAL;
+		}
+	}
+
+	if (IOH_DMA_SUCCESS == retval) {
+		/* Setting the count. */
+		retval = dma_set_count(channel, count);
+		IOH_DEBUG
+		    ("ioh_set_dma_count -> Function dma_set_count returned "
+		     "%d.\n", retval);
+	}
+
+	IOH_DEBUG("Function ioh_set_dma_count returns %d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_set_dma_count);
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn	int ioh_set_dma_desc(int channel, struct ioh_dma_desc *start,
+			struct ioh_dma_desc *end)
+	@brief		Used to set the DMA channel descriptors.
+	@remarks	Sets the DMA descriptor for the 'Scatter/Gather mode'
+				of DMA transfer. This function is invoked by
+				functions from other kernel modules. The main
+				tasks performed by this function are:
+				- Verifies whether the obtained parameters are
+				valid, if not suitable error status codes are
+				returned to the called function.
+				- If valid interacts with the HAL API to set the
+				descriptor settings and returns the status code
+				returned by the HAL API.
+	@note		This function is accessible by other kernel modules. The
+				following points have to be noted while passing
+				the "start" and "end" pointer of the descriptor.
+				- The address pointed by them should be physical
+				address with valid virtual address.
+				- The space should be alligned and accessible by
+				the DMA hardware.
+				- An easy way to perform this is to allocate the
+				descriptor memory using kmalloc.
+				- The last two bits of the physical address
+				should be suitably set so as to perform suitable
+				action after completion of each descriptor
+				action.
+				- The in-address and out-address within each
+				descriptor should be a valid memory space
+				physical address.
+
+	@param	channel	[@ref IN]	DMA channel number
+	@param	start	[@ref IN]	A pointer to the first descriptor.
+	@param	end	[@ref IN]	A pointer to the last descriptor.
+
+	@return	int
+		- @ref IOH_DMA_SUCCESS	--> On success.
+		- -EAGAIN		--> The device is in suspend.
+		- -EINVAL		--> For invalid parameters.
+		- -ENODEV		--> Specified DMA channel is not exist.
+		- -EBUSY		--> If DMA transfer is in progress or
+					channel is already enabled.
+*/
+int ioh_set_dma_desc(int channel, struct ioh_dma_desc *start,
+		     struct ioh_dma_desc *end)
+{
+	int retval;
+
+	/* Checking if the device is in suspend mode. */
+	if (1 == ioh_device_suspended) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_desc -> The device is in "
+			"suspend mode.\n");
+		retval = -EAGAIN;
+	}
+	/* Checking for validity of channel number  */
+	else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_desc -> Invalid Channel number "
+			": %d.\n", channel);
+		retval = -ENODEV;
+	}
+	/* Checking whether channel is not allocated. */
+	else if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_desc -> Channel not allocated.\n");
+		retval = -EINVAL;
+	}
+	/* Checking whether the channel is enabled. */
+	else if (ioh_dma_channel_info[channel].bChEnabled == 1) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_desc -> Channel already enabled.\n");
+		retval = -EBUSY;
+	}
+	/* Checking if the mode is other than SCATTER_GATHER. */
+	else if (ioh_dma_channel_info[channel].DMATransferMode !=
+		 (u16) DMA_SCATTER_GATHER_MODE) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_desc -> Current mode id is not "
+			"SCATTER GATHER.\n");
+		retval = -EINVAL;
+	}
+	/* Checking whether start and end pointers are NULL or not */
+	else if ((start == NULL) || (end == NULL)) {
+		IOH_LOG(KERN_ERR,
+			"ioh_set_dma_desc -> NULL pointer parameter.\n");
+		retval = -EINVAL;
+	} else {
+		/* Setting the descriptors. */
+		retval = dma_set_desc(channel, start, end);
+		IOH_DEBUG("ioh_set_dma_desc -> Function dma_set_desc "
+			  "returned %d.\n", retval);
+	}
+
+	IOH_DEBUG("Function ioh_set_dma_desc returns %d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_set_dma_desc);
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn	int ioh_add_dma_desc(int channel, struct ioh_dma_desc *start,
+			struct ioh_dma_desc *end)
+	@brief		Used to append the DMA descriptors for a channel.
+	@remarks	Used when a new chain of descriptors is to be appended
+				to the existing chain of descriptors. This
+				function is invoked by functions from other
+				modules. The main tasks performed by this
+				function are:
+				- Verifies whether the obtained parameters are
+				valid, if not suitable error status codes are
+				returned to the called function.
+				- If valid interacts with the HAL API to append
+				the descriptor settings and returns the status
+				code returned by the HAL API.
+	@note		This function is accessible by other kernel modules.
+				The following points have to be noted while
+				passing the "start" and "end" pointer of the
+				descriptor.
+				- The address pointer by them should be physical
+				address with valid virtual address.
+				- The space should be alligned and accessible by
+				the DMA hardware.
+				- An easy way to perform this is to allocate the
+				descriptor memory using kmalloc.
+				- The last two bits of the physical address
+				should be suitably set so as to perform suitable
+				action after completion of each descriptor
+				action.
+				- The in-address and out-address within each
+				descriptor should be a valid memory space
+				physical address.
+
+	@param	channel	[@ref IN]	DMA channel number
+	@param	start	[@ref IN]	A pointer to the first descriptor.
+	@param	end	[@ref IN]	A pointer to the last descriptor.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EAGAIN	--> The device is in suspend mode.
+			- -ENODEV	--> Specified DMA channel does not
+						exist.
+			- -EINVAL	--> Invalid parameters passed.
+			- -EBUSY	--> If DMA Transfer in progress or
+						channel is already enabled.
+ */
+int ioh_add_dma_desc(int channel, struct ioh_dma_desc *start,
+		     struct ioh_dma_desc *end)
+{
+	int retval;
+
+	/* Checking whether the device is in suspend mode. */
+	if (1 == ioh_device_suspended) {
+		IOH_LOG(KERN_ERR,
+			"ioh_add_dma_desc -> The device is in suspend "
+			"mode.\n");
+		retval = -EAGAIN;
+	}
+	/* Checking for validity of channel number  */
+	else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_add_dma_desc -> Invalid Channel "
+			"number : %d", channel);
+		retval = -ENODEV;
+	}
+	/* Checking whether channel is not allocated. */
+	else if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_LOG(KERN_ERR,
+			"ioh_add_dma_desc -> Channel not alloctaed.\n");
+		retval = -EINVAL;
+	}
+	/* Checking whether the channel is enabled. */
+	else if (ioh_dma_channel_info[channel].bChEnabled == 1) {
+		IOH_LOG(KERN_ERR,
+			"ioh_add_dma_desc -> Channel already enabled.\n");
+		retval = -EBUSY;
+	}
+	/* Checking whether the mode is other than SCATTER_GATHER. */
+	else if (ioh_dma_channel_info[channel].DMATransferMode !=
+		 (u16) DMA_SCATTER_GATHER_MODE) {
+		IOH_LOG(KERN_ERR,
+			"ioh_add_dma_desc -> Current mode id is not "
+			"SCATTER_GATHER.\n");
+		retval = -EINVAL;
+	}
+	/* Checking if descriptor field of the channel is set earlier. */
+	else if ((ioh_dma_channel_info[channel].pHeadOfList == NULL) ||
+		 (ioh_dma_channel_info[channel].pTailOfList == NULL)) {
+		IOH_LOG(KERN_ERR, "ioh_add_dma_desc -> Descriptor list not "
+			"set earlier.\n");
+		retval = -EINVAL;
+	}
+	/* Checking whether start and end pointers are NULL or not */
+	else if ((start == NULL) || (end == NULL)) {
+		IOH_LOG(KERN_ERR,
+			"ioh_add_dma_desc -> NULL pointer parameter.\n");
+		retval = -EINVAL;
+	} else {
+		/* Appending the descriptors to the available list. */
+		retval = dma_add_desc(channel, start, end);
+		IOH_DEBUG
+		    ("ioh_add_dma_desc -> Function dma_add_desc returned %d.\n",
+		     retval);
+	}
+
+	IOH_DEBUG("Function ioh_add_dma_desc returns %d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_add_dma_desc);
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn			int ioh_enable_dma(int channel)
+	@brief		Used to enable a DMA channel.
+	@remarks	Used when a DMA channel has to be enabled. This
+				function is invoked by functions from other
+				kernel modules. The main tasks performed by this
+				function are:
+				- Verifies whether the obtained parameters are
+				valid, if not suitable error status codes are
+				returned to the called function.
+				- If valid interacts with the HAL API to enable
+				the channel and returns the status code returned
+				by the HAL API.
+	@note		This function is accessible by other kernel modules.
+
+	@param		channel		[@ref IN]	DMA channel number .
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EAGAIN		--> Device is in suspend mode.
+			- -ENODEV		--> Specified DMA channel does
+							not exist.
+			- -EINVAL		--> Specified channel is not
+							allocated.
+			- -EBUSY		--> DMA Transfer already in
+							progress or channel is
+							already enabled.
+ */
+int ioh_enable_dma(int channel)
+{
+	int retval;
+
+	/* Checking whether the device is in suspend mode. */
+	if (ioh_device_suspended == 1) {
+		IOH_LOG(KERN_ERR, "ioh_enable_dma -> Device is in suspend "
+			"mode.\n");
+		retval = -EAGAIN;
+	}
+	/* Checking for validity of channel number  */
+	else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_enable_dma ->Invalid Channel number "
+			": %d.\n", channel);
+		retval = -ENODEV;
+	}
+	/* Checking whether channel is allocated. */
+	else if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_LOG(KERN_ERR, "ioh_enable_dma -> Channel not allocated.\n");
+		retval = -EINVAL;
+	}
+	/* Checking whether the channel is already enabled. */
+	else if (ioh_dma_channel_info[channel].bChEnabled == 1) {
+		IOH_LOG(KERN_ERR,
+			"ioh_enable_dma -> Channel already enabled.\n");
+		retval = -EBUSY;
+	} else {
+		/* Enabling the channel. */
+		retval = dma_enable_ch(channel);
+		IOH_DEBUG("ioh_enable_dma -> Function dma_enable_ch returned "
+			  "%d.\n", retval);
+	}
+
+	IOH_DEBUG("Function ioh_enable_dma returns %d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_enable_dma);
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn			int ioh_disable_dma(int channel)
+	@brief		Used to disable a DMA channel.
+	@remarks	Used when a DMA channel has to be disabled. This
+				function is invoked by functions from other
+				kernel modules. The main tasks performed by this
+				function are:
+				- Verifies whether the obtained parameters are
+				valid, if not suitable error status codes are
+				returned to the called function.
+				- If valid interacts with the HAL API to disable
+				the channel and returns the status code returned
+				by the HAL API.
+	@note		This function is accessible by other kernel modules.
+
+	@param		channel	[@ref IN]	DMA channel number .
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -ENODEV	--> Specified DMA channel does not
+						exist.
+			- -EINVAL	--> Specified channel is not allocated.
+
+ */
+int ioh_disable_dma(int channel)
+{
+	int retval;
+	u16 statusInfo;
+
+	/* Checking whether the device is in suspend mode. */
+	if (ioh_device_suspended == 1) {
+		IOH_LOG(KERN_ERR, "ioh_disable_dma -> Device is in "
+			"suspend mode.\n");
+		retval = -EAGAIN;
+	}
+	/* Checking for validity of channel number.  */
+	else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_disable_dma -> Invalid Channel "
+			"number : %d", channel);
+		retval = -ENODEV;
+	}
+	/* Checking whether channel is allocated. */
+	else if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_LOG(KERN_ERR, "ioh_disable_dma -> Channel not "
+			"allocated.\n");
+		retval = -EINVAL;
+	}
+	/* Check whether channel is already disabled. */
+	else if (ioh_dma_channel_info[channel].bChEnabled == (u16) 0) {
+		retval = IOH_DMA_SUCCESS;
+	} else {
+		u32 counter = COUNTER_LIMIT;
+
+		/* Wait for any DMA for certain interval transfer to end
+		   before disabling the channel */
+		do {
+			get_dma_status(channel, &statusInfo);
+		} while ((counter--) && (statusInfo != (u16) DMA_STATUS_IDLE));
+
+		/* Disabling the channel. */
+		retval = dma_disable_ch(channel);
+		IOH_DEBUG("ioh_disable_dma -> Function dma_disable_ch "
+			  "returned %d.\n", retval);
+
+	}
+
+	IOH_DEBUG("Function ioh_disable_dma returns " "%d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_disable_dma);
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn	int ioh_dma_set_callback(int channel,
+			void (*ioh_dma_cbr)( int value,unsigned long data1),
+			unsigned long data)
+	@brief	Used to set the callback function for particular DMA channel.
+	@remarks	Sets the callback function to be called when an
+				interrupt occurs. This function is invoked by
+				functions from other kernel modules. The main
+				tasks performed by this function are:
+				- Verifies whether the obtained parameters are
+				valid, if not suitable error status codes are
+				returned to the called function.
+				- If valid interacts with the HAL API to set the
+				callback function settings and returns the
+				status code returned by the HAL API.
+	@note		This function is accessible by other kernel modules.
+
+	@param		channel		[@ref IN]	DMA channel number .
+	@param	ioh_dma_cbr	[@ref IN]	Pointer to the call-back
+							function.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EAGAIN		--> Device is in suspend mode.
+			- -EINVAL		--> Parameter passed is invalid.
+			- -ENODEV		--> Specified DMA channel does
+							not exist.
+			- -EBUSY		--> If the channel is already
+							enabled.
+ */
+int ioh_dma_set_callback(int channel,
+			 void (*ioh_dma_cbr) (int value, unsigned long data1),
+			 unsigned long data)
+{
+	int retval;
+
+	/* Checking whether the device is in suspend mode. */
+	if (ioh_device_suspended == 1) {
+		IOH_LOG(KERN_ERR, "ioh_dma_set_callback -> The device is "
+			"in suspend mode.\n");
+		retval = -EAGAIN;
+	}
+	/* Checking for validity of channel number  */
+	else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_dma_set_callback -> Invalid Channel "
+			"number : %d.\n", channel);
+		retval = -ENODEV;
+	}
+	/* Checking whether channel is not allocated. */
+	else if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_LOG(KERN_ERR,
+			"ioh_dma_set_callback -> Channel not allocated.\n");
+		retval = -EINVAL;
+	}
+	/* Checking whether the channel is already enabled. */
+	else if (ioh_dma_channel_info[channel].bChEnabled == 1) {
+		IOH_LOG(KERN_ERR,
+			"ioh_dma_set_callback -> Channel already enabled.\n");
+		retval = -EBUSY;
+	}
+	/* Checking whether function pointer is NULL or not */
+	else if (ioh_dma_cbr == NULL) {
+		IOH_LOG(KERN_ERR,
+			"ioh_dma_set_callback -> NULL pointer parameter.\n");
+		retval = -EINVAL;
+	} else {
+		/* Setting the callback. */
+		dma_set_callback(channel, ioh_dma_cbr, data);
+		IOH_DEBUG
+		    ("ioh_dma_set_callback -> Function dma_set_callback invoked"
+		     " successfully.\n");
+
+		retval = IOH_DMA_SUCCESS;
+	}
+
+	IOH_DEBUG("Function ioh_dma_set_callback " "returns %d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_dma_set_callback);
+
+/*! @ingroup	InterfaceLayer
+	@fn		int ioh_set_dma_priority (int channel, int priority)
+	@brief		Sets the priority of the DMA channel.
+	@remarks	Sets the priority that has to be assigned for a
+				particular channel. This function is invoked by
+				functions from other kernel modules. The main
+				tasks performed by this function are:
+				- Verifies whether the obtained parameters are
+				valid, if not, suitable error status codes are
+				returned to the called function.
+				- If valid, interacts with the HAL API to set
+				the DMA channel priority settings and returns
+				the status code returned by the HAL API.
+	@note		This function is accessible by other kernel modules.
+
+	@param	channel		[@ref IN]	DMA channel number.
+	@param	priority	[@ref IN]	Priority to be set for the
+							DMA channel.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EAGAIN	--> Device is in suspend mode.
+			- -EINVAL	--> Parameter passed is invalid.
+			- -EBUSY	--> If channel is in use.
+			- -ENODEV	--> Specified DMA channel does not
+						exist.
+
+ */
+int ioh_set_dma_priority(int channel, int priority)
+{
+	int retval;
+
+	/* Checking whether the device is in suspend mode. */
+	if (ioh_device_suspended == 1) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_priority -> The device is "
+			"in suspend mode.\n");
+		retval = -EAGAIN;
+	}
+	/* Checking for validity of channel number  */
+	else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_priority -> Invalid Channel "
+			"number : %d", channel);
+		retval = -ENODEV;
+	}
+	/* Checking whether channel is not allocated. */
+	else if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_priority -> Channel not "
+			"allocated.\n");
+		retval = -EINVAL;
+	}
+	/* Checking whether the device is enabled. */
+	else if (ioh_dma_channel_info[channel].bChEnabled == 1) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_priority -> Channel already "
+			"enabled.\n");
+		retval = -EBUSY;
+	}
+	/* Check for validity of priority value */
+	else if ((priority > 3) || (priority < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_set_dma_priority -> Invalid value "
+			"priority (%d)", priority);
+		retval = -EINVAL;
+	} else {
+		retval = dma_set_priority(channel, priority);
+		IOH_DEBUG("ioh_set_dma_priority -> Function dma_set_priority "
+			  "returns %d.\n", retval);
+	}
+
+	IOH_DEBUG("Function ioh_set_dma_priority returns " "%d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_set_dma_priority);
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn			int ioh_dma_direct_start (int channel)
+	@brief		Used to initiate a DMA transfer.
+	@remarks	Generates the DMA request to begin DMA transfer
+				on a particular channel. This function is
+				invoked by functions from other kernel modules.
+				The main tasks performed by this function are:
+				- Verifies whether the obtained parameters are
+				valid, if not suitable error status codes are
+				returned to the called function.
+				- If valid interacts with the HAL API to
+				initiate the DMA process and returns the status
+				code returned by the HAL API.
+	@note		This function is accessible by other kernel modules.
+
+	@param		channel  DMA channel number.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EAGAIN	--> Device is in suspend mode.
+			- -EBUSY	--> Specified DMA channel is not idle.
+			- -ENODEV	--> Specified DMA channel does not
+						exist.
+			- -EINVAL	--> Specified channel is not allocated.
+
+ */
+int ioh_dma_direct_start(int channel)
+{
+	int retval = 0;
+
+	/* Checking whether the device is in suspend mode. */
+	if (ioh_device_suspended == 1) {
+		IOH_LOG(KERN_ERR, "ioh_dma_direct_start -> The device is in "
+			"suspend mode.\n");
+		retval = -EAGAIN;
+	}
+	/* Checking for validity of channel number  */
+	else if ((channel >= IOH_DMA_CHANNELS_MAX) || (channel < 0)) {
+		IOH_LOG(KERN_ERR, "ioh_dma_direct_start -> Invalid Channel "
+			"number : %d.\n", channel);
+		retval = -ENODEV;
+	}
+	/* Checking whether channel is reserved or not */
+	else if (ioh_dma_channel_table[channel].ch_alloced == (u16) 0) {
+		IOH_LOG(KERN_ERR, "ioh_dma_direct_start -> Channel not "
+			"allocated.\n");
+		retval = -EINVAL;
+	}
+	/* Checking whether the device is not enabled. */
+	else if (ioh_dma_channel_info[channel].bChEnabled == 0) {
+		IOH_LOG(KERN_ERR, "ioh_dma_direct_start -> Channel not "
+			"enabled.\n");
+		retval = -EBUSY;
+	} else {
+		/* Initiating the DMA transfer */
+		retval = dma_direct_start(channel);
+		IOH_DEBUG("ioh_dma_direct_start -> Function dma_direct_start "
+			  "returned %d.\n", retval);
+	}
+
+	IOH_DEBUG("Function ioh_dma_direct_start returns " "%d.\n", retval);
+	return retval;
+}
+EXPORT_SYMBOL(ioh_dma_direct_start);
--- /dev/null
+++ b/drivers/dma/pch_dma/pch_dma_main.h
@@ -0,0 +1,264 @@
+/**
+ * @file ioh_dma_main.h
+ *
+ * @brief
+ *		This file declares the structures & data types used by the
+ *		IOH_DMA driver.
+ *
+ * @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.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 08/14/2009
+ *
+ */
+
+#ifndef __IOH_DMA_H__
+#define __IOH_DMA_H__
+
+/*!	@ingroup	InterfaceLayer
+	@def		DMA_ONE_SHOT_MODE
+	@brief		Constant used to denote the mode as ONE_SHOT.
+	@note		This constant is used by other modules to make the
+				DMA module aware of the mode it requires.
+*/
+#define DMA_ONE_SHOT_MODE			(0x2U)
+
+/*!	@ingroup	InterfaceLayer
+	@def		DMA_SCATTER_GATHER_MODE
+	@brief		Constant used to denote the mode as SCATTER_GATHER.
+	@note		This constant is used by other modules to make the
+				DMA module aware of the mode it requires.
+*/
+#define DMA_SCATTER_GATHER_MODE		(0x1U)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_DMA_SIZE_TYPE_8BIT
+	@brief		Constant used to denote the access size as 8BIT.
+	@note		This constant is used by other modules to make the
+				DMA module aware of the access size it requires.
+*/
+#define IOH_DMA_SIZE_TYPE_8BIT			((0x3U << 12))
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_DMA_SIZE_TYPE_16BIT
+	@brief		Constant used to denote the access size as 16BIT.
+	@note		This constant is used by other modules to make the
+				DMA module aware of the access size it requires.
+*/
+#define IOH_DMA_SIZE_TYPE_16BIT			((0x2U << 12))
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_DMA_SIZE_TYPE_32BIT
+	@brief		Constant used to denote the access size as 32BIT.
+	@note		This constant is used by other modules to make the
+				DMA module aware of the access size it requires.
+*/
+#define IOH_DMA_SIZE_TYPE_32BIT			(0x0U)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_DMA_DIR_OUT_TO_IN
+	@brief		Constant used to denote the transfer direction as
+				OUT_TO_IN.
+	@note		This constant is used by other modules to make the
+				DMA module aware of the transfer direction it
+				requires.
+*/
+#define IOH_DMA_DIR_OUT_TO_IN				(0x4)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_DMA_DIR_IN_TO_OUT
+	@brief		Constant used to denote the transfer direction as
+				IN_TO_OUT.
+	@note		This constant is used by other modules to make the
+				DMA module aware of the transfer direction it
+				requires.
+*/
+#define IOH_DMA_DIR_IN_TO_OUT				(0x0)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_DMA_END
+	@brief		Constant used to denote the transfer status as ACCESS
+	@note		This constant is used by DMA modules to make the
+				other module aware that the DMA operation ended
+				normally.
+*/
+#define IOH_DMA_END							(0)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_DMA_ABORT
+	@brief		Constant used to denote the transfer status as ACCESS
+	@note		This constant is used by DMA modules to make the
+				other module aware that the DMA abort has
+				occurred.
+*/
+#define IOH_DMA_ABORT						(-1)
+
+/* Bits to be sit as LSB2 bits of descriptor address. */
+/*!	@ingroup	InterfaceLayer
+	@def		DMA_DESC_END_WITH_INTERRUPT
+	@brief		Mask value for modifying the next descriptor
+				address, so that the descriptor end with
+				interrupt.
+*/
+#define DMA_DESC_END_WITH_INTERRUPT	(0x00000001UL)
+
+/*!	@ingroup	InterfaceLayer
+	@def		DMA_DESC_FOLLOW_WITH_INTERRUPT
+	@brief		Mask value for modifying the next descriptor
+				address, so that the descriptor follow with
+				interrupt.
+
+*/
+#define DMA_DESC_FOLLOW_WITH_INTERRUPT	(0x00000003UL)
+
+/*!	@ingroup	InterfaceLayer
+	@def		DMA_DESC_END_WITHOUT_INTERRUPT
+	@brief		Mask value for modifying the next descriptor
+				address, so that the descriptor end without
+				interrupt.
+*/
+#define DMA_DESC_END_WITHOUT_INTERRUPT	(0x00000000UL)
+
+/*!	@ingroup	InterfaceLayer
+	@def		DMA_DESC_FOLLOW_WITHOUT_INTERRUPT
+	@brief		Mask value for modifying the next descriptor
+				address, so that the descriptor follow without
+				interrupt.
+
+*/
+#define DMA_DESC_FOLLOW_WITHOUT_INTERRUPT	(0x00000002UL)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_DMA_8BIT_COUNT_MAX
+	@brief		The maximun transfer count that can be set for
+				a 8Bit Access.
+
+*/
+#define IOH_DMA_8BIT_COUNT_MAX	(0x3FF)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_DMA_16BIT_COUNT_MAX
+	@brief		The maximun transfer count that can be set for
+				a 16Bit Access.
+
+*/
+#define IOH_DMA_16BIT_COUNT_MAX	(0x3FF)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_DMA_32BIT_COUNT_MAX
+	@brief		The maximun transfer count that can be set for
+				a 32Bit Access.
+
+*/
+#define IOH_DMA_32BIT_COUNT_MAX	(0x7FF)
+
+/*!	@ingroup	DMA
+	@def		IOH_DMA_SUCCESS
+	@brief		The value indicating a success.
+*/
+#define IOH_DMA_SUCCESS				(0)
+
+/*!	@ingroup	DMA
+	@def		IOH_DMA_FAILURE
+	@brief		The value indicating a failure.
+*/
+#define IOH_DMA_FAILURE				(-1)
+
+/*!	@ingroup	InterfaceLayerFacilitators
+	@enum		ioh_channel_request_id
+	@brief		Constant used to denote the channel request type.
+	@note		These constants are used by other modules to make the
+				DMA module aware of the channel type it
+				requires.
+*/
+enum ioh_channel_request_id {
+	IOH_DMA_TX_DATA_REQ0 = 1,	/**< Transmission channel 0. */
+	IOH_DMA_RX_DATA_REQ0,		/**< Reception channel 0. */
+	IOH_DMA_TX_DATA_REQ1,		/**< Transmission channel 1. */
+	IOH_DMA_RX_DATA_REQ1,		/**< Reception channel 1. */
+	IOH_DMA_TX_DATA_REQ2,		/**< Transmission channel 2. */
+	IOH_DMA_RX_DATA_REQ2,		/**< Reception channel 2. */
+	IOH_DMA_TX_DATA_REQ3,		/**< Transmission channel 3. */
+	IOH_DMA_RX_DATA_REQ3,		/**< Reception channel 3. */
+	IOH_DMA_TX_DATA_REQ4,		/**< Transmission channel 4. */
+	IOH_DMA_RX_DATA_REQ4,		/**< Reception channel 4. */
+	IOH_DMA_TX_DATA_REQ5,		/**< Transmission channel 5. */
+	IOH_DMA_RX_DATA_REQ5		/**< Reception channel 5. */
+};
+
+/*!	@ingroup	InterfaceLayerFacilitators
+	@struct		__ioh_dma_mode_param
+	@brief		Format for specifying the mode characteristics of
+				a channel.
+	@note		This structure is used by other modules to make the
+				DMA module aware of the channel mode
+				characteristics.
+*/
+
+struct ioh_dma_mode_param {
+	u16 TransferDirection;	/**< Direction of Transfer(IN to OUT or OUT to
+				IN). */
+	u16 DMASizeType;	/**< Type of DMA Transfer size (8bit, 16bit or
+				32bit). */
+	u16 DMATransferMode;	/**< Mode of Transfer (ONE_SHOT_MODE or
+				SCATTER_GATHER_MODE). */
+};
+
+/*!	@ingroup	InterfaceLayerFacilitators
+	@struct		__ioh_dma_desc
+	@brief		Format for specifying the descriptors.
+	@note		This structure is used by other modules to make the
+				DMA module aware of the channel descriptors in
+				SCATTER_GATHER_MODE.
+*/
+
+struct ioh_dma_desc {
+	u32 insideAddress;     /**< Inside address.		*/
+	u32 outsideAddress;    /**< Outside address.		*/
+	u32 size;	       /**< Size.			*/
+	u32 nextDesc;	       /**< Next Descriptor address.*/
+};
+
+extern int ioh_request_dma(struct pci_dev *dev, int dreq);
+extern int ioh_free_dma(int channel);
+extern int ioh_set_dma_mode(int channel, struct ioh_dma_mode_param stModeParam);
+extern int ioh_set_dma_addr(int channel, unsigned int iaddr,
+			    unsigned int oaddr);
+extern int ioh_set_dma_count(int channel, unsigned int count);
+extern int ioh_set_dma_desc(int channel, struct ioh_dma_desc *start,
+			    struct ioh_dma_desc *end);
+extern int ioh_add_dma_desc(int channel, struct ioh_dma_desc *start,
+			    struct ioh_dma_desc *end);
+extern int ioh_enable_dma(int channel);
+extern int ioh_disable_dma(int channel);
+extern int ioh_dma_set_callback(int channel,
+				void (*ioh_dma_cbr) (int value,
+						     unsigned long data1),
+				unsigned long data);
+extern int ioh_set_dma_priority(int channel, int priority);
+extern int ioh_dma_direct_start(int channel);
+
+#endif
--- /dev/null
+++ b/drivers/dma/pch_dma/pch_dma_pci.c
@@ -0,0 +1,694 @@
+/**
+ * @file ioh_dma_pci.c
+ *
+ * @brief
+ *		This file defines the methods of IOH_DMA_CONTROLLER driver.
+ *
+ * @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.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 08/14/2009
+ *
+ */
+
+/* inclusion of system specific header files. */
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+/* inclusion of module specific header files. */
+#include "pch_debug.h"
+#include "pch_dma_pci.h"
+#include "pch_dma_hal.h"
+
+MODULE_LICENSE("GPL");
+
+/* Global variables */
+
+/*!	@ingroup	Global
+	@var		MODULE_NAME
+	@brief		The module name variable.
+	@remarks	This variable is used as the module name.
+*/
+#define MODULE_NAME "pch_dma"
+/*!	@ingroup	Global
+	@var		ioh_device_suspended
+	@brief		Device suspend flag.
+	@remarks	This variable is used as a flag variable
+				for denoting the device suspend state.
+	@see
+		- ioh_dma_suspend
+		- ioh_dma_resume
+*/
+unsigned char ioh_device_suspended;
+
+/*!	@ingroup	Global
+	@var		ioh_device_lock
+	@brief		Device lock variable.
+	@remarks	This variable is used as a lock variable
+				for accessing the DMA channel.
+	@see
+		- ioh_request_dma
+*/
+spinlock_t ioh_device_lock;
+
+/*!	@ingroup	Global
+	@var		ioh_dma_devices
+	@brief		Stores the details of the DMA devices.
+	@remarks	This variable is the instance of the structure
+				struct ioh_dma_devices, which includes fields
+				for storing the details of the detected DMA
+				devices. This variable facilitates easy transfer
+				of information among the different functions of
+				the DMA module.
+*/
+struct ioh_dma_devices ioh_dma_devices[IOH_DMA_MAX_DEVS];
+
+/*!	@ingroup	PCILayerFacilitators
+	@struct		ioh_dma_pcidev_id
+	@brief		The structure for specifying the supported
+				device IDs to the PCI Kernel subsystem.
+	@remarks	This structure is the instance of the
+				kernel provided structure pci_device_id,
+				which is used to store the PCI devices
+				Vendor and Device ID. This structure is
+				used during the registration of the DMA module
+				as PCI Driver. This structure makes the Kernel
+				aware of the PCI devices supported by this
+				module.
+
+	@see
+		- ioh_dma_controller_driver
+*/
+
+static const struct pci_device_id ioh_dma_pcidev_id[] __devinitdata = {
+	/* 4 Channel DMA device IDs */
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOH1_DMA4_0)},
+
+	/* 8 Channel DMA device IDs */
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOH1_DMA8_0)},
+
+	/* 12 Channel DMA device IDs */
+	{}
+};
+
+/* Function prototypes */
+static int __devinit ioh_dma_probe(struct pci_dev *pdev,
+				   const struct pci_device_id *id);
+static void __devexit ioh_dma_remove(struct pci_dev *pdev);
+static int ioh_dma_suspend(struct pci_dev *pdev, pm_message_t state);
+static int ioh_dma_resume(struct pci_dev *pdev);
+static __init int ioh_dma_pci_init(void);
+static __exit void ioh_dma_pci_exit(void);
+static inline u32 get_dev_type(u32 devid);
+
+/*!	@ingroup	PCILayer
+	@def		IOH_INVALID_DEVICE
+	@brief		The return value of @ref get_dev_type for invalid
+				device type.
+
+	@see
+		-	get_dev_type
+*/
+#define IOH_INVALID_DEVICE			(0xFFFF)
+
+/*!	@ingroup	InternalFunction
+	@fn			static inline u32 get_dev_type (u32 devid)
+	@brief		Returns the IOH device type for given PCI device id.
+	@remarks	This function returns the type of the detected DMA
+				device. The type specifies the number of DMA
+				channels contained within the detected device.
+				The tasks performed by this function include:
+				- Matches the PCI device ID passed to it with a
+				set of known device IDs.
+				- If a match is found it returns a constant
+				which indicates the device type (number of DMA
+				channels) within the device.
+				- If no match is found it returns @ref
+				IOH_INVALID_DEVICE.
+
+	@param		devid	[@ref IN]	The device ID to be verified.
+
+	@return		u32
+			-	Values other than @ref IOH_INVALID_DEVICE
+					-->	Detected device is valid and
+					supported.
+			-	@ref IOH_INVALID_DEVICE	--> Invalid device
+					detected.
+
+	@see
+			- ioh_dma_probe
+
+*/
+static inline u32 get_dev_type(u32 devid)
+{
+	u32 dev_type;
+
+	switch (devid) {
+	case PCI_DEVICE_ID_INTEL_IOH1_DMA4_0:
+		dev_type = IOH_DMA_4CH0;
+		break;
+
+	case PCI_DEVICE_ID_INTEL_IOH1_DMA8_0:
+		dev_type = IOH_DMA_8CH0;
+		break;
+
+	default:
+		IOH_LOG(KERN_ERR, "get_dev_type -> Unknown PCI "
+			"device 0x%x\n", devid);
+		dev_type = IOH_INVALID_DEVICE;
+		break;
+
+	}
+
+	IOH_DEBUG("Function get_dev_type returns %x.\n", dev_type);
+	return dev_type;
+}
+
+/*!	@ingroup	PCILayerAPI
+	@fn		static int __devinit ioh_dma_probe(struct pci_dev* pdev,
+				const struct pci_device_id* id)
+	@brief		Implements the probe function for the PCI driver.
+	@remarks	This function acts as the probe function for
+				the PCI driver. The PCI core will be invoking
+				this function once it determines that this
+				driver is suitable for handling a particular
+				hardware. The main tasks performed by this
+				function are:
+				- Confirms whether the detected device is
+				supported by the driver.
+				- Enables the PCi device.
+				- Attains the device specific resources and
+				store it for further use.
+				- Enables the device and registers the handler
+				for handling the device interrupts.
+				- Initializes the device specific data
+				structures.
+
+	@param		pdev	[@ref INOUT]	Reference to the pci_device
+				structure.
+	@param		id	[@ref IN]	Reference to the pci_device_id
+				for which this device matches.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EIO		--> pci_enable_device error status code.
+			- -EBUSY:	--> pci_request_regions/request_irq
+				error status code.
+			- -EINVAL	--> pci_enable_device/request_irq error
+				status code/invalid device ID.
+			- -ENOMEM	--> request_irq/pci_iomap error status
+				code.
+			- -ENOSYS	--> request_irq error status code.
+
+	@see
+			- ioh_dma_controller_driver
+  */
+static int __devinit ioh_dma_probe(struct pci_dev *pdev,
+				   const struct pci_device_id *id)
+{
+	static unsigned int ioh_dma_dcount;
+	int retval;
+	u32 dev_type;
+	u32 base_addr = 0;
+	u8 device_enabled = 0;
+	u8 regions_requested = 0;
+	u8 irq_registered = 0;
+
+	do {
+		/* Getting the internally used device ID of the detected
+		device. */
+		dev_type = get_dev_type(id->device);
+		/* If invalid device. */
+		if ((IOH_INVALID_DEVICE == dev_type)) {
+			IOH_LOG(KERN_ERR, "ioh_dma_probe -> Invalid device ID "
+				"%x.\n", id->device);
+			retval = -EINVAL;
+			break;
+		}
+		IOH_DEBUG("ioh_dma_probe -> Valid device ID detected %x.\n",
+			  id->device);
+
+		/* Enabling the detected device */
+		retval = pci_enable_device(pdev);
+		if (0 != retval) {
+			IOH_LOG(KERN_ERR,
+				"ioh_dma_probe -> Function pci_enable_device "
+				"failed, returned %d.\n", retval);
+			break;
+		}
+		device_enabled = 1;
+		IOH_DEBUG
+		    ("ioh_dma_probe -> Function pci_enable_device invoked "
+		    "successfully returned %d.\n", retval);
+
+		pci_set_master(pdev);
+		IOH_DEBUG("ioh_dma_probe -> Function pci_set_master invoked "
+			  "successfully.\n");
+
+		/* Requesting the PCI device regions. */
+		retval = pci_request_regions(pdev, MODULE_NAME);
+		if (0 != retval) {
+			IOH_LOG(KERN_ERR,
+				"ioh_dma_probe -> Function pci_request_regions "
+				"failed, returned %d.\n", retval);
+			break;
+		}
+		regions_requested = 1;
+		IOH_DEBUG
+		    ("ioh_dma_probe -> Function pci_request_regions invoked "
+		    "successfully returned %d.\n", retval);
+
+		/* Remapping the device space to kernel space. */
+		/* Wipro 1/13/2010 Use Mem BAR */
+		base_addr = (u32) pci_iomap(pdev, 1, 0);
+		if (0 == base_addr) {
+			IOH_LOG(KERN_ERR,
+				"ioh_dma_probe -> Function pci_iomap failed "
+				"returned %x.\n", base_addr);
+			retval = -ENOMEM;
+			break;
+		}
+		IOH_DEBUG
+		    ("ioh_dma_probe -> Function pci_iomap invoked successfully."
+		     "\n");
+
+		/* Filling in the details within the device structure. */
+		ioh_dma_devices[ioh_dma_dcount].dev_typ = dev_type;
+		ioh_dma_devices[ioh_dma_dcount].base_addr = base_addr;
+		ioh_dma_devices[ioh_dma_dcount].dev = (void *)pdev;
+
+		/* Registering the interrupt handler. */
+		retval =
+		    request_irq(pdev->irq, dma_interrupt, IRQF_SHARED,
+				MODULE_NAME, &ioh_dma_devices[ioh_dma_dcount]);
+		if (0 != retval) {
+			IOH_LOG(KERN_ERR,
+				"ioh_dma_probe -> Function request_irq failed, "
+				"returned %d.\n", retval);
+
+			break;
+		}
+		irq_registered = 1;
+		IOH_DEBUG
+		    ("ioh_dma_probe -> Function request_irq invoked "
+		     "successfully returned %d.\n", retval);
+
+		/* Initializing the DMA device. */
+		dma_init(base_addr, dev_type);
+		IOH_DEBUG
+		    ("ioh_dma_probe -> Function dma_init invoked successfully."
+		     "\n");
+
+		/* Stroing the device structure reference for further use. */
+		pci_set_drvdata(pdev, &ioh_dma_devices[ioh_dma_dcount]);
+
+		/* Initializing the suspend flag and lock variable. */
+		if (0 == ioh_dma_dcount) {	/* Initialize only once. */
+			ioh_device_suspended = 0;
+			spin_lock_init(&ioh_device_lock);
+		}
+
+		/* Incrementing the device structure index. */
+		ioh_dma_dcount++;
+
+		/* Probe successful. */
+		retval = IOH_DMA_SUCCESS;
+		IOH_DEBUG("ioh_dma_probe -> Probe successful.\n");
+
+	} while (0);
+
+	if (IOH_DMA_SUCCESS != retval) {
+		/* Un-registering the interrupt handler. */
+		if (1 == irq_registered) {
+			free_irq(pdev->irq, &ioh_dma_devices[ioh_dma_dcount]);
+			IOH_DEBUG("ioh_dma_probe -> Function free_irq invoked "
+				  "successfully.\n");
+		}
+		/* Unmapping the remapped region. */
+		if (0 != base_addr) {
+			pci_iounmap(pdev, (void *)base_addr);
+			IOH_DEBUG
+			    ("ioh_dma_probe -> Function pci_iounmap invoked "
+			     "successfully.\n");
+		}
+		/* Releasing the requested regions. */
+		if (1 == regions_requested) {
+			pci_release_regions(pdev);
+			IOH_DEBUG
+			    ("ioh_dma_probe -> Function pci_release_regions "
+			    "invoked successfully.\n");
+		}
+		/* Disabling the device. */
+		if (1 == device_enabled) {
+			pci_disable_device(pdev);
+			IOH_DEBUG
+			    ("ioh_dma_probe -> Function pci_disable_device "
+			    "invoked successfully.\n");
+		}
+
+		IOH_DEBUG("ioh_dma_probe -> Probe failed.\n");
+	}
+
+	IOH_DEBUG("Function ioh_dma_probe returns %d.\n", retval);
+	return retval;
+}
+
+/*!	@ingroup	PCILayerAPI
+	@fn	static void __devexit ioh_dma_remove(struct pci_dev* pdev)
+	@brief		Implements the remove function for the PCi driver.
+	@remarks	This function is invoked by the PCI subsystem of the
+				Kernel when the DMA device is removed or the
+				module is unloaded.
+				It de-initializes and releases all the resources
+				attained during device detection. The main tasks
+				performed by this function are:
+				- De-initializes the DMA device.
+				- De-initializes the device specific data
+				structures.
+				- Releases all the resources attained during the
+				device detection phase.
+
+	@param	pdev	[@ref INOUT]	Reference to the pci_device structure.
+
+	@return		None.
+
+	@see
+			- ioh_dma_controller_driver
+  */
+static void __devexit ioh_dma_remove(struct pci_dev *pdev)
+{
+	struct ioh_dma_devices *dev;
+
+	/* Getting the driver data. */
+	dev = pci_get_drvdata(pdev);
+	/* Re-setting the driver data. */
+	pci_set_drvdata(pdev, NULL);
+
+	/* De-initializing the device. */
+	dma_exit(dev->dev_typ);
+	IOH_DEBUG("ioh_dma_remove -> Function dma_exit invoked "
+		  "successfully.\n");
+
+	/* Un-registering the interrupt handler. */
+	free_irq(pdev->irq, dev);
+	IOH_DEBUG("ioh_dma_remove -> Function free_irq invoked "
+		  "successfully.\n");
+
+	/* Un-mapping the remapped memory address. */
+	pci_iounmap(pdev, (void *)dev->base_addr);
+	dev->base_addr = 0;
+	IOH_DEBUG("ioh_dma_remove -> Function pci_iounmap invoked "
+		  "successfully.\n");
+
+	/* Releasing the requested regions. */
+	pci_release_regions(pdev);
+	IOH_DEBUG("ioh_dma_remove -> Function pci_release_regions "
+		  "invoked successfully.\n");
+
+	/* Disabling the device. */
+	pci_disable_device(pdev);
+	IOH_DEBUG("ioh_dma_remove -> Function pci_disable_device "
+		  "invoked successfully.\n");
+
+	IOH_DEBUG("Function ioh_dma_remove invoked  "
+		  "successfully for device %x.\n", pdev->device);
+}
+
+#ifdef CONFIG_PM
+/*!	@ingroup	PCILayerAPI
+	@fn		static int ioh_dma_suspend(struct pci_dev* pdev,
+				pm_message_t state)
+	@brief		Implements the suspend function for the pci_driver.
+	@remarks	This function is used as the suspend function of the PCI
+				Driver.
+				The PCI core will be invoking this function once
+				it receives a suspend event from the PM layer.
+				The main tasks performed by this functions are:
+				- Prepares the device so that it can enter the
+				suspend state by saving the current state.
+				- Disables all the DMA channels and the
+				associated interrupts.
+				- Changes the power state of the device to low
+				power state.
+
+	@param	pdev	[@ref INOUT]	Reference to the pci_device structure.
+	@param	state	[@ref IN]	The state of the device.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -ENOMEM	--> pci_save_state error status code.
+
+	@see
+			- ioh_dma_controller_driver
+  */
+static int ioh_dma_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int retval;
+	struct ioh_dma_devices *dev;
+
+	/* Setting flag for denoting Suspension. */
+	ioh_device_suspended = 1;
+
+	/* Getting the driver data. */
+	dev = pci_get_drvdata(pdev);
+
+	/* Saving the current state of the device. */
+	retval = pci_save_state(pdev);
+	if (retval == 0) {
+		IOH_DEBUG("ioh_dma_suspend -> Function pci_save_state invoked "
+			  "successfully (returned %d).\n", retval);
+
+		/* De-initializing the device for suspension. */
+		dma_exit(dev->dev_typ);
+		IOH_DEBUG("ioh_dma_suspend -> Function dma_exit invoked "
+			  "successfully.\n");
+
+		/* Disabling the wake-up feature. */
+		pci_enable_wake(pdev, PCI_D3hot, 0);
+		IOH_DEBUG("ioh_dma_suspend -> Function pci_enable_wake "
+			  "invoked successfully.\n");
+
+		/* Setting the device to new state. */
+		pci_set_power_state(pdev, pci_choose_state(pdev, state));
+		IOH_DEBUG("ioh_dma_suspend -> Function pci_set_power_state "
+			  "invoked successfully.\n");
+
+		/* Disabling the device. */
+		pci_disable_device(pdev);
+		IOH_DEBUG("ioh_dma_suspend -> Function pci_disable_device "
+			  "invoked successfully.\n");
+
+		retval = IOH_DMA_SUCCESS;
+		IOH_DEBUG("ioh_dma_suspend -> Suspension successful for "
+			  "the device %x.\n", pdev->device);
+	} else {
+		IOH_LOG(KERN_ERR,
+			"ioh_dma_suspend -> Function pci_save_state failed"
+			"returned %d.\n", retval);
+
+		/* De-setting the flag on Suspend failure. */
+		ioh_device_suspended = 0;
+
+		IOH_DEBUG("ioh_dma_suspend -> Suspension un-successful for "
+			  "the device %x.\n", pdev->device);
+	}
+
+	IOH_DEBUG("Function ioh_dma_suspend returns %d.\n", retval);
+	return retval;
+}
+
+/*!	@ingroup	PCILayerAPI
+	@fn			static int ioh_dma_resume(struct pci_dev* pdev)
+	@brief		Implements the resume function for the pci_driver.
+	@remarks	This function is used as the resume function of the
+				PCI driver. The PCI core will be invoking this
+				function once it receives a resume event from
+				the PM layer. The main tasks performed by this
+				function are:
+				- Restores the power state of the device to
+				normal state.
+				- Enables the device so that it returns to its
+				normal state.
+
+	@param		pdev	[@ref INOUT]	Pointer to the pci_device
+				structure.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EIO		--> pci_enable_device error status code.
+			- -EINVAL	--> pci_enable_device .
+
+	@see
+			- ioh_dma_controller_driver
+
+  */
+static int ioh_dma_resume(struct pci_dev *pdev)
+{
+	int retval;
+
+	/* Setting the device to normal power state. */
+	(void)pci_set_power_state(pdev, PCI_D0);
+	IOH_DEBUG("ioh_dma_resume -> Function pci_set_power_state invoked "
+		  "successfully.\n");
+
+	/* Restoring the device state. */
+	(void)pci_restore_state(pdev);
+	IOH_DEBUG("ioh_dma_resume -> Function pci_restore_state invoked "
+		  "successfully.\n");
+
+	/* Enabling the device. */
+	retval = pci_enable_device(pdev);
+
+	if (0 == retval) {
+		IOH_DEBUG("ioh_dma_resume -> Function pci_enable_device "
+			  "invoked successfully returned %d.\n", retval);
+
+		pci_set_master(pdev);
+		IOH_DEBUG("ioh_dma_resume -> Function pci_set_master invoked "
+			  "successfully.\n");
+
+		(void)pci_enable_wake(pdev, PCI_D3hot, 0);
+		IOH_DEBUG("ioh_dma_resume -> Function pci_enable_wake invoked "
+			  "successfully.\n");
+
+		retval = IOH_DMA_SUCCESS;
+
+		/* De-setting the suspend flag to denote resumption
+		successful. */
+		ioh_device_suspended = 0;
+
+		IOH_DEBUG("ioh_dma_resume -> Resume successful for the "
+			  "device %x.\n", pdev->device);
+	} else {
+		IOH_LOG(KERN_ERR,
+			"ioh_dma_resume -> Function pci_enable_device failed "
+			"returned %d.\n", retval);
+
+		IOH_DEBUG("ioh_dma_resume -> Resume failed for the device "
+			  "%x.\n", pdev->device);
+	}
+
+	IOH_DEBUG("Function ioh_dma_resume returns %d.\n", retval);
+	return retval;
+}
+#endif
+
+/*!	@ingroup	PCILayerFacilitators
+	@struct		ioh_dma_controller_driver
+	@brief		Used for registering the PCI driver functionalities.
+	@remarks	This is an instance of the structure pci_driver which
+				stores references to the PCI Driver
+				functionalities.
+				It is used during PCI driver registration for
+				interfacing the DMA module functionalities with
+				that of the Kernel subsystem.
+
+	@see
+			- ioh_dma_pci_init
+			- ioh_dma_pci_exit
+*/
+
+static struct pci_driver ioh_dma_controller_driver = {
+	.name = "ioh_dma",		/**< Name of the module. */
+	.id_table = ioh_dma_pcidev_id,	/**< The list of supported devices. */
+	.probe = ioh_dma_probe,		/**< The probe function. */
+	.remove = __devexit_p(ioh_dma_remove),	/**< The remove function. */
+#ifdef CONFIG_PM
+	.suspend = ioh_dma_suspend,	/**< The suspend function. */
+	.resume = ioh_dma_resume	/**< The resume function. */
+#endif
+};
+
+/*!	@ingroup	PCILayerAPI
+	@fn			static __init int ioh_dma_pci_init(void)
+	@brief		Module initialization routine.
+	@remarks	This function is invoked when the module is
+				loaded. The main tasks performed by this
+				function are:
+				- Initializes the module.
+				- Initializes the local structures
+				and registers the module as PCI Driver
+				with the kernel subsystem.
+
+	@return	int
+			- @ref IOH_DMA_SUCCESS	--> On success.
+			- -EEXIST	--> pci_register_driver error status
+						code.
+			- -EINVAL	--> pci_register_driver error status
+						code.
+			- -ENOMEM	--> pci_register_driver error status
+						code.
+
+  */
+static __init int ioh_dma_pci_init(void)
+{
+	int retval;
+
+	/* Registering the module as PCI Driver. */
+	retval = pci_register_driver(&ioh_dma_controller_driver);
+
+	if (0 == retval) {
+		IOH_DEBUG
+		    ("ioh_dma_pci_init -> Function pci_register_driver invoked "
+		     "successfully returned %d.\n", retval);
+
+		retval = IOH_DMA_SUCCESS;
+	} else {
+		IOH_LOG(KERN_ERR,
+			"ioh_dma_pci_init -> Function pci_register_driver "
+			"failed returned %d.\n", retval);
+	}
+
+	IOH_DEBUG("Function ioh_dma_pci_init returns %d.\n", retval);
+	return retval;
+}
+
+/*!	@ingroup	PCILayerAPI
+	@fn			static __exit void ioh_dma_pci_exit(void)
+	@brief		Module exit handler.
+	@remarks	Kernel subsystem will be invoking this routine
+				once the module gets unloaded. The main tasks
+				performed by this function are:
+				- Un-registers the PCI driver.
+				- Unloads the module.
+
+	@return		None.
+  */
+static __exit void ioh_dma_pci_exit(void)
+{
+	/* Un-registering the module as PCI Driver. */
+	pci_unregister_driver(&ioh_dma_controller_driver);
+	IOH_DEBUG("ioh_dma_pci_exit -> Function pci_unregister_driver "
+		  "invoked successfully.\n");
+
+	IOH_DEBUG("Function ioh_dma_pci_exit invoked successfully.\n");
+}
+
+MODULE_DEVICE_TABLE(pci, ioh_dma_pcidev_id);
+module_init(ioh_dma_pci_init);
+module_exit(ioh_dma_pci_exit);
--- /dev/null
+++ b/drivers/dma/pch_dma/pch_dma_pci.h
@@ -0,0 +1,74 @@
+/**
+ * @file ioh_dma_pci.h
+ *
+ * @brief
+ * This file declares the constants & functions used by the
+ *  IOH_DMA_CONTROLLER driver.
+ *
+ * @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.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 08/14/2009
+ *
+ */
+
+#ifndef __IOH_DMA_PCI_H__
+#define __IOH_DMA_PCI_H__
+
+/*!	@ingroup	PCILayer
+	@def		PCI_DEVICE_ID_INTEL_IOH1_DMA4_0
+	@brief		The Device ID of one of the DMA device
+				with 4 channels used for the GE devices.
+	@note		This is used for registering the DMA module
+				with the PCI subsystem of the Kernel, so that
+				the module is loaded when the required device
+				is detected.
+
+	@see
+		- ioh_dma_pcidev_id
+		- get_dev_type
+*/
+#define PCI_DEVICE_ID_INTEL_IOH1_DMA4_0		(0x8815UL)
+
+/*!	@ingroup	PCILayer
+	@def		PCI_DEVICE_ID_DMA8_0_CONTROLLER
+	@brief		The Device ID of one of the DMA device
+				with 8 channels used for the GE devcies.
+	@note		This is used for registering the DMA module
+				with the PCI subsystem of the Kernel, so that
+				the module is loaded when the required device
+				is detected.
+
+	@see
+		- ioh_dma_pcidev_id
+		- get_dev_type
+*/
+#define PCI_DEVICE_ID_INTEL_IOH1_DMA8_0		(0x8810UL)
+
+extern unsigned char ioh_device_suspended;	/* The device suspend flag.  */
+extern spinlock_t ioh_device_lock;	/* The device lock variable. */
+
+#endif
