aboutsummaryrefslogtreecommitdiffstats
path: root/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-dma.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-dma.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-dma.patch4133
1 files changed, 4133 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-dma.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-dma.patch
new file mode 100644
index 0000000000..e3fddb2df7
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-dma.patch
@@ -0,0 +1,4133 @@
+---
+ 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