summaryrefslogtreecommitdiff
path: root/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-spi.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-spi.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-spi.patch4377
1 files changed, 0 insertions, 4377 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-spi.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-spi.patch
deleted file mode 100644
index 43129c728..000000000
--- a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-spi.patch
+++ /dev/null
@@ -1,4377 +0,0 @@
-From: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
-Subject: OKI Semiconductor PCH SPI driver
-
-This driver implements SPI controls for PCH.
-
-Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
-Acked-by: Wang Qi <qi.wang@intel.com>
-
----
- drivers/spi/Kconfig | 19 ++
- drivers/spi/Makefile | 3
- drivers/spi/pch_common.h | 146
- drivers/spi/pch_spi.h | 389
- drivers/spi/pch_spi_hal.h | 298
- drivers/spi/pch_spi_pci.c | 812
- drivers/spi/pch_debug.h | 60
- drivers/spi/pch_spi_hal.c | 1208
- drivers/spi/pch_spi_main.c | 1323
- drivers/spi/pch_spi_platform_devices.c | 50
-
-+++++++++++++++++++++++++++++++ 10 files changed, yyy insertions(+)
-diff -urN linux-2.6.33-rc3/drivers/spi/Kconfig topcliff-2.6.33-rc3/drivers/spi/Kconfig
---- linux-2.6.33-rc3/drivers/spi/Kconfig 2010-01-06 09:02:46.000000000 +0900
-+++ topcliff-2.6.33-rc3/drivers/spi/Kconfig 2010-03-06 07:48:16.000000000 +0900
-@@ -53,6 +53,25 @@
-
- comment "SPI Master Controller Drivers"
-
-+config PCH_SPI_PLATFORM_DEVICE
-+ bool "PCH SPI Device"
-+# depends on PCH_SPI
-+ help
-+ This registers SPI devices for using with PCH SPI controllers.
-+
-+config PCH_SPI_PLATFORM_DEVICE_COUNT
-+ int "PCH SPI Bus count"
-+ range 1 2
-+ depends on PCH_SPI_PLATFORM_DEVICE
-+ help
-+ The number of SPI buses/channels supported by the PCH SPI controller.
-+
-+config PCH_SPI
-+ tristate "PCH SPI Controller"
-+ depends on (PCI) && PCH_SPI_PLATFORM_DEVICE
-+ help
-+ This selects a driver for the PCH SPI Controller
-+
- config SPI_ATMEL
- tristate "Atmel SPI Controller"
- depends on (ARCH_AT91 || AVR32)
-diff -urN linux-2.6.33-rc3/drivers/spi/Makefile topcliff-2.6.33-rc3/drivers/spi/Makefile
---- linux-2.6.33-rc3/drivers/spi/Makefile 2010-01-06 09:02:46.000000000 +0900
-+++ topcliff-2.6.33-rc3/drivers/spi/Makefile 2010-03-06 01:52:28.000000000 +0900
-@@ -59,3 +59,6 @@
-
- # SPI slave drivers (protocol for that link)
- # ... add above this line ...
-+obj-$(CONFIG_PCH_SPI) += pch_spi.o
-+pch_spi-objs := pch_spi_pci.o pch_spi_hal.o pch_spi_main.o
-+obj-$(CONFIG_PCH_SPI_PLATFORM_DEVICE) +=pch_spi_platform_devices.o
-diff -urN linux-2.6.33-rc3/drivers/spi/pch_common.h topcliff-2.6.33-rc3/drivers/spi/pch_common.h
---- linux-2.6.33-rc3/drivers/spi/pch_common.h 1970-01-01 09:00:00.000000000 +0900
-+++ topcliff-2.6.33-rc3/drivers/spi/pch_common.h 2010-03-09 05:56:11.000000000 +0900
-@@ -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
-diff -urN linux-2.6.33-rc3/drivers/spi/pch_debug.h topcliff-2.6.33-rc3/drivers/spi/pch_debug.h
---- linux-2.6.33-rc3/drivers/spi/pch_debug.h 1970-01-01 09:00:00.000000000 +0900
-+++ topcliff-2.6.33-rc3/drivers/spi/pch_debug.h 2010-03-09 05:37:47.000000000 +0900
-@@ -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
-diff -urN linux-2.6.33-rc3/drivers/spi/pch_spi.h topcliff-2.6.33-rc3/drivers/spi/pch_spi.h
---- linux-2.6.33-rc3/drivers/spi/pch_spi.h 1970-01-01 09:00:00.000000000 +0900
-+++ topcliff-2.6.33-rc3/drivers/spi/pch_spi.h 2010-03-06 09:01:42.000000000 +0900
-@@ -0,0 +1,389 @@
-+#ifndef __IOH_SPI_H__
-+#define __IOH_SPI_H__
-+/**
-+ * @file ioh_spi.h
-+ *
-+ * @brief This header file contains all macro,structure and function
-+ * declarations
-+ * for IOH SPI driver.
-+ * @version 0.94
-+ *
-+ * @par
-+ * -- Copyright Notice --
-+ *
-+ * @par
-+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
-+ * All rights reserved.
-+ *
-+ * @par
-+ * 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.
-+ *
-+ * @par
-+ * -- End of Copyright Notice --
-+ */
-+
-+/*! @defgroup SPI */
-+
-+/*! @defgroup SPI_Global
-+@ingroup SPI
-+@brief This group describes the global entities within
-+ the module.
-+@remarks This group includes all the global data structures
-+ used within the modules. These are mainly used to
-+ store the device related information, so that it can
-+ be used by other functions of the modules.
-+<hr>
-+*/
-+
-+/*! @defgroup SPI_PCILayer
-+@ingroup SPI
-+@brief This group describes the PCI layer interface
-+ functionalities.
-+@remarks This group contains the functions and data structures
-+ that are used to interface the module with PCI Layer
-+ subsystem of the Kernel.
-+<hr>
-+*/
-+
-+/*! @defgroup SPI_InterfaceLayer
-+@ingroup SPI
-+@brief This group describes the Driver interface functionalities.
-+@remarks This group contains the data structures and functions used
-+ to interface the module driver with the kernel subsystem.
-+<hr>
-+*/
-+
-+/*! @defgroup SPI_HALLayer
-+@ingroup SPI
-+@brief This group describes the hardware specific functionalities.
-+@remarks This group contains the functions and data structures used
-+ by the module to communicate with the hardware. These
-+ functions are device specific and designed according to the
-+ device specifications.
-+<hr>
-+*/
-+
-+/*! @defgroup SPI_Utilities
-+@ingroup SPI
-+@brief This group describes the utility functionalities.
-+@remarks This group contains the functions and data structures used
-+ to assist the other functionalities in their operations.
-+<hr>
-+*/
-+
-+/*! @defgroup SPI_PCILayerAPI
-+@ingroup SPI_PCILayer
-+@brief This group contains the API(functions) used as the PCI
-+ interface between the Kernel subsystem and the module.
-+<hr>
-+*/
-+
-+/*! @defgroup SPI_PCILayerFacilitators
-+@ingroup SPI_PCILayer
-+@brief This group contains the data structures used by the PCI
-+ Layer APIs for their functionalities.
-+<hr>
-+*/
-+
-+/*! @defgroup SPI_InterfaceLayerAPI
-+@ingroup SPI_InterfaceLayer
-+@brief This group contains the API(functions) used as the Driver
-+ interface between the Kernel subsystem and the module.
-+<hr>
-+*/
-+
-+/*! @defgroup SPI_InterfaceLayerFacilitators
-+@ingroup SPI_InterfaceLayer
-+@brief This group contains the data structures used by the Driver
-+ interface APIs for their functionalities.
-+<hr>
-+*/
-+
-+/*! @defgroup SPI_HALLayerAPI
-+@ingroup SPI_HALLayer
-+@brief This group contains the APIs(functions) used to interact with
-+ the hardware. These APIs act as an interface between the
-+ hardware and the other driver functions.
-+<hr>
-+*/
-+
-+/*! @defgroup SPI_UtilitiesAPI
-+@ingroup SPI_Utilities
-+@brief This group contains the APIs(functions) used by other functions
-+ in their operations.
-+<hr>
-+*/
-+
-+#include <linux/wait.h>
-+#include <linux/device.h>
-+#include <linux/pci.h>
-+#include <linux/spi/spi.h>
-+#include <linux/workqueue.h>
-+
-+/*! @ingroup SPI_Global
-+
-+@def STATUS_RUNNING
-+
-+@brief SPI channel is running
-+
-+@note The status of SPI channel is set to STATUS_RUNNING,
-+ once all resources are acquired and initialized from
-+ @ref ioh_spi_get_resources
-+
-+@see
-+ - ioh_spi_get_resources
-+
-+<hr>
-+*/
-+#define STATUS_RUNNING (1)
-+
-+/*! @ingroup SPI_Global
-+
-+@def STATUS_EXITING
-+
-+@brief SPI device is being removed
-+
-+@note The status of SPI channel is set to STATUS_EXITING,
-+ when SPI device is being removed.
-+
-+@see
-+ - ioh_spi_process_messages
-+ - ioh_spi_check_request_pending
-+
-+<hr>
-+*/
-+#define STATUS_EXITING (2)
-+
-+/*! @ingroup SPI_Global
-+
-+@def DRIVER_NAME
-+
-+@brief Name identifier for IOH SPI driver
-+
-+@note This name is used while printing debug logs
-+
-+<hr>
-+*/
-+#define DRIVER_NAME "ioh_spi"
-+
-+/*! @ingroup SPI_Global
-+
-+@def IOH_SPI_SLEEP_TIME
-+
-+@brief Sleep time used in @ref ioh_spi_check_request_pending
-+
-+@see
-+ - ioh_spi_check_request_pending
-+
-+<hr>
-+*/
-+#define IOH_SPI_SLEEP_TIME (10)
-+
-+/*! @ingroup SPI_Global
-+
-+@def IOH_SPI_MAX_DEV
-+
-+@brief Denotes Maximum number of SPI channels
-+
-+@note This needs to be edited if number of SPI channels
-+ change.
-+
-+@see
-+ - ioh_spi_get_resources
-+ - ioh_spi_free_resources
-+ - ioh_spi_handler
-+ - ioh_spi_check_request_pending
-+ - ioh_spi_probe
-+ - ioh_spi_suspend
-+ - ioh_spi_resume
-+ - ioh_spi_remove
-+
-+<hr>
-+*/
-+#ifdef IOH_DEVICE_GE
-+#define IOH_SPI_MAX_DEV (1)
-+#else
-+#define IOH_SPI_MAX_DEV (1)
-+#endif
-+
-+/*! @ingroup SPI_Global
-+
-+@def IOH_SPI_ADDRESS_SIZE
-+
-+@brief Denotes the address range used by one SPI channel.
-+
-+@note The base address of a subsequent SPI channel will be
-+ (base address of the previous SPI channel) + (IOH_SPI_ADDRESS_SIZE)
-+ This needs to be recalculated if any new register is added to a SPI
-+ channel.
-+
-+@see
-+ - ioh_spi_get_resources
-+
-+<hr>
-+*/
-+#define IOH_SPI_ADDRESS_SIZE (0x20)
-+
-+/*structures*/
-+
-+/*! @ingroup SPI_Global
-+@struct ioh_spi_data
-+@brief Holds the SPI channel specific details
-+
-+ This structure holds all the details related to a SPI channel
-+
-+ The status of SPI data transfer,the base address are all
-+ stored in this structure.The reference to the work queue handler,
-+ the SPI message and transmit and receive indices are also stored
-+ in this structure.
-+
-+@see
-+ - ioh_spi_board_data
-+ - ioh_spi_select_chip
-+ - ioh_spi_deselect_chip
-+ - ioh_spi_transfer
-+ - ioh_spi_process_messages
-+<hr>
-+*/
-+
-+struct ioh_spi_data {
-+
-+ u32 IORemapAddress; /**< The remapped PCI base address.*/
-+
-+ /**< The SPI master structure that has been registered
-+ with the Kernel.*/
-+ struct spi_master *pMaster;
-+
-+ struct work_struct Work; /**< Reference to work queue handler*/
-+
-+ /**< Workqueue for carrying out execution of the requests*/
-+ struct workqueue_struct *pWorkQueue;
-+
-+ /**< Wait queue for waking up upon receiving an interrupt.*/
-+ wait_queue_head_t Wait;
-+
-+ u8 bTransferComplete; /**< Status of SPI Transfer*/
-+ u8 bCurrent_msg_processing; /**< Status flag for message processing*/
-+
-+ spinlock_t Lock; /**< Lock for protecting this structure*/
-+
-+ struct list_head Queue; /**< SPI Message queue*/
-+ u8 Status; /**< Status of the SPI driver.*/
-+
-+ u32 lengthInBpw;/**< Length of data to be transferred in bits per word*/
-+ s8 bTransferActive; /**< Flag showing active transfer*/
-+ u32 TxIndex;/**< Transmit data count; for bookkeeping during transfer*/
-+ u32 RxIndex;/**< Receive data count; for bookkeeping during transfer*/
-+ u16 *pU16TxBuffer; /**< Data to be transmitted*/
-+ u16 *pU16RxBuffer; /**< Received data*/
-+
-+/**< The chip number that this SPI driver currently operates on*/
-+ u8 nCurrentChip;
-+
-+ /**< Reference to the current chip that this SPI driver currently
-+ operates on*/
-+ struct spi_device *pCurrentChip;
-+
-+ /**< The current message that this SPI driver is handling*/
-+ struct spi_message *pCurMsg;
-+
-+ /**< The current transfer that this SPI driver is handling*/
-+ struct spi_transfer *pCurTransfer;
-+
-+ /**< Reference to the SPI device data structure*/
-+ struct ioh_spi_board_data *pBoardData;
-+};
-+
-+/*! @ingroup SPI_Global
-+@struct ioh_spi_board_data
-+@brief Holds the SPI device specific details
-+
-+ This structure holds all the details related to a SPI device.
-+
-+ The reference to the pci_dev structure,status of request_irq,
-+ pci_request_regions and device suspend are all stored in this structure.
-+
-+ This structure also has an array of pointers to ioh_spi_data structures,
-+ with each pointer holding the details of one spi channel.
-+
-+@see
-+ - ioh_spi_data
-+ - ioh_spi_check_request_pending
-+ - ioh_spi_get_resources
-+ - ioh_spi_free_resources
-+ - ioh_spi_remove
-+ - ioh_spi_suspend
-+ - ioh_spi_resume
-+ - ioh_spi_probe
-+ - ioh_spi_handler
-+<hr>
-+*/
-+
-+struct ioh_spi_board_data {
-+
-+ struct pci_dev *pDev; /**< Reference to the PCI device*/
-+ u8 bIrqRegistered; /**< Status of IRQ registration*/
-+ u8 bRegionRequested; /**< Status of pci_request_regions*/
-+ u8 bSuspended; /**< Status of suspend*/
-+
-+ /**< Reference to SPI channel data structure*/
-+ struct ioh_spi_data *pCtrlData[IOH_SPI_MAX_DEV];
-+};
-+
-+/*function prototypes*/
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+@fn ioh_spi_callback( struct ioh_spi_data* pCtrlData)
-+@brief Callback function
-+*/
-+void ioh_spi_callback(struct ioh_spi_data *pCtrlData);
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+@fn ioh_spi_free_resources(struct ioh_spi_board_data* pBoardData)
-+@brief Frees the resources acquired by IOH SPI driver
-+*/
-+void ioh_spi_free_resources(struct ioh_spi_board_data *pBoardData);
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+@fn ioh_spi_check_request_pending(struct ioh_spi_board_data* pBoardData)
-+@brief Checks for any pending SPI transfer request in the queue of pending
-+ transfers
-+*/
-+int ioh_spi_check_request_pending(struct ioh_spi_board_data *pBoardData);
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+@fn ioh_spi_get_resources(struct ioh_spi_board_data* pBoardData)
-+@brief Acquires the resources for IOH SPI driver
-+*/
-+int ioh_spi_get_resources(struct ioh_spi_board_data *pBoardData);
-+
-+/*! @ingroup SPI_InterfaceLayerAPI
-+@fn ioh_spi_setup(struct spi_device* pSpi)
-+@brief Implements the setup routine for IOH SPI driver
-+*/
-+int ioh_spi_setup(struct spi_device *pSpi);
-+
-+/*! @ingroup SPI_InterfaceLayerAPI
-+@fn ioh_spi_transfer(struct spi_device* pSpi,struct spi_message* pMsg)
-+@brief Implements the transfer routine for IOH SPI driver
-+*/
-+int ioh_spi_transfer(struct spi_device *pSpi, struct spi_message *pMsg);
-+
-+/*! @ingroup SPI_InterfaceLayerAPI
-+@fn ioh_spi_cleanup(struct spi_device* pSpi)
-+@brief Implements the cleanup routine for IOH SPI driver
-+*/
-+void ioh_spi_cleanup(struct spi_device *pSpi);
-+
-+#endif
-diff -urN linux-2.6.33-rc3/drivers/spi/pch_spi_hal.c topcliff-2.6.33-rc3/drivers/spi/pch_spi_hal.c
---- linux-2.6.33-rc3/drivers/spi/pch_spi_hal.c 1970-01-01 09:00:00.000000000 +0900
-+++ topcliff-2.6.33-rc3/drivers/spi/pch_spi_hal.c 2010-03-09 00:41:44.000000000 +0900
-@@ -0,0 +1,1208 @@
-+/**
-+ * @file ioh_spi_hal.c
-+ *
-+ * @brief This file defines the HAL methods .
-+ *
-+ * @version 0.94
-+ *
-+ * @par
-+ * -- Copyright Notice --
-+ *
-+ * @par
-+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
-+ * All rights reserved.
-+ *
-+ * @par
-+ * 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.
-+ *
-+ * @par
-+ * -- End of Copyright Notice --
-+ */
-+
-+#include <linux/io.h>
-+#include <linux/interrupt.h>
-+#include "pch_common.h"
-+#include "pch_debug.h"
-+#include "pch_spi.h"
-+#include "pch_spi_hal.h"
-+
-+/*bit positions in SPCR*/
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_SPE_BIT
-+@brief SPE bit position in SPCR
-+@see
-+ - ioh_spi_set_enable
-+*/
-+#define SPCR_SPE_BIT (1 << 0)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_MSTR_BIT
-+@brief MSTR bit position in SPCR
-+@see
-+ - ioh_spi_set_master_mode
-+*/
-+#define SPCR_MSTR_BIT (1 << 1)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_LSBF_BIT
-+@brief LSBF bit position in SPCR
-+@see
-+ - ioh_spi_setup_transfer
-+*/
-+#define SPCR_LSBF_BIT (1 << 4)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_CPHA_BIT
-+@brief CPHA bit position in SPCR
-+@see
-+ - ioh_spi_setup_transfer
-+*/
-+#define SPCR_CPHA_BIT (1 << 5)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_CPOL_BIT
-+@brief CPOL bit position in SPCR
-+@see
-+ - ioh_spi_setup_transfer
-+*/
-+#define SPCR_CPOL_BIT (1 << 6)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_TFIE_BIT
-+@brief TFIE bit position in SPCR
-+@see
-+ - ioh_spi_enable_interrupts
-+ - ioh_spi_disable_interrupts
-+*/
-+#define SPCR_TFIE_BIT (1 << 8)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_RFIE_BIT
-+@brief RFIE bit position in SPCR
-+@see
-+ - ioh_spi_enable_interrupts
-+ - ioh_spi_disable_interrupts
-+*/
-+#define SPCR_RFIE_BIT (1 << 9)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_FIE_BIT
-+@brief FIE bit position in SPCR
-+@see
-+ - ioh_spi_enable_interrupts
-+ - ioh_spi_disable_interrupts
-+*/
-+#define SPCR_FIE_BIT (1 << 10)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_ORIE_BIT
-+@brief ORIE bit position in SPCR
-+@see
-+ - ioh_spi_enable_interrupts
-+ - ioh_spi_disable_interrupts
-+*/
-+#define SPCR_ORIE_BIT (1 << 11)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_MDFIE_BIT
-+@brief MDFIE bit position in SPCR
-+@see
-+ - ioh_spi_enable_interrupts
-+ - ioh_spi_disable_interrupts
-+*/
-+#define SPCR_MDFIE_BIT (1 << 12)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_FICLR_BIT
-+@brief FICLR bit position in SPCR
-+@see
-+ - ioh_spi_clear_fifo
-+*/
-+#define SPCR_FICLR_BIT (1 << 24)
-+
-+/*bit positions in SPSR*/
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPSR_TFI_BIT
-+@brief TFI bit position in SPCR
-+*/
-+#define SPSR_TFI_BIT (1 << 0)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPSR_RFI_BIT
-+@brief RFI bit position in SPCR
-+@see
-+ - ioh_spi_handler
-+*/
-+#define SPSR_RFI_BIT (1 << 1)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPSR_FI_BIT
-+@brief FI bit position in SPCR
-+@see
-+ - ioh_spi_handler
-+*/
-+#define SPSR_FI_BIT (1 << 2)
-+
-+/*bit positions in SPBRR*/
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPBRR_SIZE_BIT
-+@brief SIZE bit position in SPCR
-+@see
-+ - ioh_spi_set_bits_per_word
-+*/
-+#define SPBRR_SIZE_BIT (1 << 10)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_RFIC_FIELD
-+@brief RFIC field in SPCR
-+@see
-+ - ioh_spi_set_threshold
-+*/
-+#define SPCR_RFIC_FIELD (20)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPCR_TFIC_FIELD
-+@brief TFIC field in SPCR
-+@see
-+ - ioh_spi_set_threshold
-+*/
-+#define SPCR_TFIC_FIELD (16)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SPSR_INT_BITS
-+@brief Mask for all interrupt bits in SPSR
-+@see
-+ - ioh_spi_reset
-+*/
-+#define SPSR_INT_BITS (0x1F)
-+
-+/*! @ingroup SPI_HALLayer
-+@def MASK_SPBRR_SPBR_BITS
-+@brief Mask for clearing SPBR in SPBRR
-+@see
-+ - ioh_spi_set_baud_rate
-+*/
-+#define MASK_SPBRR_SPBR_BITS (0xFFFFFC00)
-+
-+/*! @ingroup SPI_HALLayer
-+@def MASK_RFIC_SPCR_BITS
-+@brief Mask for Rx threshold in SPCR
-+@see
-+ - ioh_spi_set_threshold
-+*/
-+#define MASK_RFIC_SPCR_BITS (0xFF0FFFFF)
-+
-+/*! @ingroup SPI_HALLayer
-+@def MASK_TFIC_SPCR_BITS
-+@brief Mask for Tx threshold in SPCR
-+@see
-+ - ioh_spi_set_threshold
-+*/
-+#define MASK_TFIC_SPCR_BITS (0xFFF0FFF)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_CLOCK_HZ
-+@brief Pclock Freqeuncy
-+@see
-+ - ioh_spi_set_baud_rate
-+*/
-+#ifndef FPGA
-+ /*LSI*/
-+#define IOH_CLOCK_HZ (50000000)
-+#else
-+ /*FPGA*/
-+#define IOH_CLOCK_HZ (62500000)
-+#endif
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_MAX_SPBR
-+@brief Maximum value possible for SPBR in SPBRR
-+@see
-+ - ioh_spi_set_baud_rate
-+*/
-+#define IOH_SPI_MAX_SPBR (1023)
-+/*global*/
-+/*! @ingroup SPI_HALLayer
-+
-+@var ioh_spi_gcbptr
-+
-+@brief SPI_Global function pointer to store reference of
-+ callback function @ref
-+ ioh_spi_callback
-+
-+@note The reference of callback function is assigend to this
-+ pointer
-+ from @ref ioh_spi_probe function by invoking
-+ the function @ref ioh_spi_entcb.
-+ This global variable is used by the function
-+ @ref ioh_spi_hanlder
-+ to invoke the callback function.
-+
-+@see
-+ - ioh_spi_entcb
-+ - ioh_spi_handler
-+
-+<hr>
-+
-+*/
-+static void (*ioh_spi_gcbptr) (struct ioh_spi_data *);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_set_master_mode( struct spi_master *master)
-+
-+@remarks Sets the MSTR bit in SPCR
-+
-+ The main task performed by this method:
-+ - Read the content of SPCR register
-+ - Set the MSTR bit
-+ - Write back the value to SPCR
-+
-+@note This function is invoked from @ref ioh_spi_probe to put the IOH SPI
-+ device into master mode.
-+
-+@param master [@ref IN] Contains reference to struct spi_master
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_probe
-+
-+<hr>
-+
-+*/
-+void ioh_spi_set_master_mode(struct spi_master *master)
-+{
-+ u32 reg_spcr_val;
-+ reg_spcr_val = ioh_spi_readreg(master, IOH_SPI_SPCR);
-+ IOH_DEBUG("ioh_spi_set_master_mode SPCR content=%x\n", reg_spcr_val);
-+
-+ /*sets the second bit of SPCR to 1:master mode */
-+ IOH_SET_BITMSK(reg_spcr_val, SPCR_MSTR_BIT);
-+
-+ /*write the value to SPCR register */
-+ ioh_spi_writereg(master, IOH_SPI_SPCR, reg_spcr_val);
-+ IOH_DEBUG("ioh_spi_set_master_mode SPCR after setting MSTR bit=%x\n",
-+ reg_spcr_val);
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_set_enable(const struct spi_device *spi, u8 enable)
-+
-+@remarks Sets/Resets the SPE bit in SPCR
-+
-+ The main tasks performed by this method are:
-+ - Read the content of SPCR.
-+ - If the enable parameter is true , set the SPE bit.
-+ - If the enable paramter is false , clear the SPE bit.
-+ - Write back the value to SPCR.
-+
-+@note This function is invoked by @ref ioh_spi_process_messages to enable SPI
-+ transfer before start of SPI data transfer and to disable SPI data
-+ transfer
-+ after completion of SPI data transfer.
-+
-+@param spi [@ref IN] Contains reference to struct spi_device
-+
-+@param enable [@ref IN]
-+ To enable SPI transfer enable = true
-+ To disable SPI transfer enable = false
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_process_messages
-+
-+<hr>
-+
-+*/
-+void ioh_spi_set_enable(const struct spi_device *spi, u8 enable)
-+{
-+ u32 reg_spcr_val;
-+
-+ reg_spcr_val = ioh_spi_readreg(spi->master, IOH_SPI_SPCR);
-+ IOH_DEBUG("ioh_spi_set_enable SPCR content=%x\n", reg_spcr_val);
-+
-+ if (enable == true) {
-+ IOH_DEBUG("ioh_spi_set_enable enable==true\n");
-+ IOH_SET_BITMSK(reg_spcr_val, SPCR_SPE_BIT);
-+ } else {
-+ IOH_DEBUG("ioh_spi_set_enable enable==false\n");
-+ IOH_CLR_BITMSK(reg_spcr_val, SPCR_SPE_BIT);
-+ }
-+
-+ ioh_spi_writereg(spi->master, IOH_SPI_SPCR, reg_spcr_val);
-+
-+ IOH_DEBUG("ioh_spi_set_enable SPCR content after modifying SPE=%x\n",
-+ reg_spcr_val);
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_handler(int irq, void* dev_id)
-+
-+@remarks Interrupt handler
-+
-+The main tasks performed by this method are:
-+- Check if Corresponding interrupt bits are set in SPSR register.
-+- If no, return IRQ_NONE.
-+- If yes, read the number of bytes received and write required number of bytes
-+according to space available.
-+- Update all bookkeeping variables.
-+- If bytes/words to be received is less than 16bytes/words,then disable RFI
-+and set Rx threshold to 16 bytes/words.
-+- If SPI data transfer is completed, invoke the callback function
-+@ref ioh_spi_callback to inform the status to @ref ioh_spi_process_messages.
-+- Repeat for all SPI channels.
-+
-+@note
-+This is the interrupt handler for IOH SPI controller driver.This function is
-+invoked by the kernel when any interrupt occurs on the interrupt line shared by
-+IOH SPI device. The SPI data transfer is initiated by @ref ioh_spi_process_
-+messages,but is carried on by this function.For optimised operation,the HAL
-+functions to read and write registers are not used in this function.
-+Also register
-+address calculation is done once at the beginning to avoid the calculation each
-+time while accessing registers.
-+
-+@param irq [@ref IN] The interrupt number
-+
-+@param dev_id [@ref IN] Contains reference to struct ioh_spi_board_data
-+
-+@retval irqreturn_t
-+ - IRQ_NONE The interrupt is not ours
-+ - IRQ_HANDLED The interrupt has been serviced
-+
-+@see
-+ - ioh_spi_get_resources
-+ - ioh_spi_free_resources
-+ - ioh_spi_suspend
-+ - ioh_spi_resume
-+
-+<hr>
-+
-+*/
-+irqreturn_t ioh_spi_handler(int irq, void *dev_id)
-+{
-+ /*channel & read/write indices */
-+ int dev, readcnt;
-+
-+ /*SPSR content */
-+ u32 reg_spsr_val, reg_spcr_val;
-+
-+ /*book keeping variables */
-+ u32 nReadable, TxIndex, RxIndex, lengthInBpw;
-+
-+ /*to hold channel data */
-+
-+ struct ioh_spi_data *pCtrlData;
-+
-+ /*buffer to store rx/tx data */
-+ u16 *pU16RxBuffer, *pU16TxBuffer;
-+
-+ /*register addresses */
-+ u32 SPSR, SPDRR, SPDWR;
-+
-+ /*remapped pci base address */
-+ u32 IORemapAddress;
-+
-+ irqreturn_t tRetVal = IRQ_NONE;
-+
-+ struct ioh_spi_board_data *pBoardData =
-+ (struct ioh_spi_board_data *)dev_id;
-+
-+ if (pBoardData->bSuspended == true) {
-+ IOH_DEBUG("ioh_spi_handler returning due to suspend\n");
-+ } else {
-+ for (dev = 0; dev < IOH_SPI_MAX_DEV; dev++) {
-+ pCtrlData = pBoardData->pCtrlData[dev];
-+ IORemapAddress = pCtrlData->IORemapAddress;
-+ SPSR = IORemapAddress + IOH_SPI_SPSR;
-+
-+ reg_spsr_val = IOH_READ_LONG(SPSR);
-+
-+ /*Check if the interrupt is for SPI device */
-+
-+ if (reg_spsr_val & (SPSR_FI_BIT | SPSR_RFI_BIT)) {
-+ IOH_DEBUG("SPSR in ioh_spi_handler=%x\n",
-+ reg_spsr_val);
-+ /*clear interrupt */
-+ IOH_WRITE_LONG(reg_spsr_val, SPSR);
-+
-+ if (pCtrlData->bTransferActive == true) {
-+ RxIndex = pCtrlData->RxIndex;
-+ TxIndex = pCtrlData->TxIndex;
-+ lengthInBpw = pCtrlData->lengthInBpw;
-+ pU16RxBuffer = pCtrlData->pU16RxBuffer;
-+ pU16TxBuffer = pCtrlData->pU16TxBuffer;
-+
-+ SPDRR = IORemapAddress + IOH_SPI_SPDRR;
-+ SPDWR = IORemapAddress + IOH_SPI_SPDWR;
-+
-+ nReadable =
-+ IOH_SPI_READABLE(reg_spsr_val);
-+
-+ for (readcnt = 0; (readcnt < nReadable);
-+ readcnt++) {
-+ /*read data */
-+ pU16RxBuffer[RxIndex++] =
-+ IOH_READ_LONG(SPDRR);
-+ /*write data */
-+
-+ if (TxIndex < lengthInBpw) {
-+ IOH_WRITE_LONG
-+ (pU16TxBuffer
-+ [TxIndex++],
-+ SPDWR);
-+ }
-+ }
-+
-+ /*disable RFI if not needed */
-+ if ((lengthInBpw - RxIndex) <=
-+ IOH_SPI_MAX_FIFO_DEPTH) {
-+ IOH_DEBUG
-+ ("ioh_spi_handler disabling\
-+ RFI as data remaining=%d\n",
-+ (lengthInBpw - RxIndex));
-+
-+ reg_spcr_val =
-+ IOH_READ_LONG(IORemapAddress
-+ +
-+ IOH_SPI_SPCR);
-+
-+ /*disable RFI */
-+ IOH_CLR_BITMSK(reg_spcr_val,
-+ SPCR_RFIE_BIT);
-+
-+ /*reset rx threshold */
-+ reg_spcr_val &=
-+ MASK_RFIC_SPCR_BITS;
-+ reg_spcr_val |=
-+ (IOH_SPI_RX_THOLD_MAX <<
-+ SPCR_RFIC_FIELD);
-+
-+ IOH_WRITE_LONG(IOH_CLR_BITMSK
-+ (reg_spcr_val,
-+ SPCR_RFIE_BIT),
-+ (IORemapAddress +
-+ IOH_SPI_SPCR));
-+ }
-+
-+ /*update counts */
-+ pCtrlData->TxIndex = TxIndex;
-+
-+ pCtrlData->RxIndex = RxIndex;
-+
-+ IOH_DEBUG
-+ ("ioh_spi_handler RxIndex=%d\n",
-+ RxIndex);
-+
-+ IOH_DEBUG
-+ ("ioh_spi_handler TxIndex=%d\n",
-+ TxIndex);
-+
-+ IOH_DEBUG
-+ ("ioh_spi_handler nWritable=%d\n",
-+ (16 -
-+ (IOH_SPI_WRITABLE
-+ (reg_spsr_val))));
-+
-+ IOH_DEBUG
-+ ("ioh_spi_handler nReadable=%d\n",
-+ nReadable);
-+ }
-+
-+ /*if transfer complete interrupt */
-+ if (reg_spsr_val & SPSR_FI_BIT) {
-+ IOH_DEBUG
-+ ("ioh_spi_handler FI bit in SPSR\
-+ set\n");
-+
-+ /*disable FI & RFI interrupts */
-+ ioh_spi_disable_interrupts(pCtrlData->
-+ pMaster,
-+ IOH_SPI_FI |
-+ IOH_SPI_RFI);
-+
-+ /*transfer is completed;inform
-+ ioh_spi_process_messages */
-+
-+ if (ioh_spi_gcbptr != NULL) {
-+ IOH_DEBUG
-+ ("ioh_spi_handler invoking\
-+ callback\n");
-+ (*ioh_spi_gcbptr) (pCtrlData);
-+ }
-+ }
-+
-+ tRetVal = IRQ_HANDLED;
-+ }
-+ }
-+ }
-+
-+ IOH_DEBUG("ioh_spi_handler EXIT return value=%d\n", tRetVal);
-+
-+ return tRetVal;
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_entcb (void (*ioh_spi_cb)( struct ioh_spi_data* ))
-+
-+@remarks Registers the callback function
-+
-+ The major tasks performed by this method are:
-+ - Validate ioh_spi_cb
-+ - Assign it to global pointer @ref ioh_spi_gcbptr
-+
-+@note This function is invoked from @ref ioh_spi_probe function
-+ This function should always be invoked before the interrupt
-+ handler is registered.
-+
-+@param ioh_spi_cb [@ref IN]
-+ Contains reference to callback function pointer
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_probe
-+
-+<hr>
-+
-+*/
-+void ioh_spi_entcb(void (*ioh_spi_cb) (struct ioh_spi_data *))
-+{
-+ if (ioh_spi_cb != NULL) {
-+ /*Assign the above value to a global pointer */
-+ ioh_spi_gcbptr = ioh_spi_cb;
-+ IOH_DEBUG("ioh_spi_entcb ioh_spi_cb ptr not NULL\n");
-+ IOH_DEBUG
-+ ("ioh_spi_entcb ioh_spi_cb ptr saved in ioh_spi_gcbptr\n");
-+ } else {
-+ IOH_LOG(KERN_ERR, "ioh_spi_entcb ioh_spi_cb ptr NULL\n");
-+ }
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_setup_transfer(struct spi_device *spi)
-+
-+@remarks Configures the IOH SPI hardware for transfer
-+
-+ The major tasks performed by this method are:
-+ - Invoke @ref ioh_spi_set_baud_rate to set the baud rate.
-+ - Invoke @ref ioh_spi_set_bits_per_word to set the bits per word.
-+ - Set the bit justfication in SPCR.
-+ - Set the Clock Polarity and Clock Phase in SPCR.
-+ - Clear the Rx and Tx FIFO by toggling FICLR bit in SPCR.
-+
-+@note This function configures the IOH SPI hardware according to the
-+ configurations specified by the user.
-+
-+@param spi [@ref IN] Contains reference to struct spi_device
-+
-+@retval int
-+ @ref IOH_SPI_SUCCESS All hardware configurations have been done
-+
-+@see
-+ - ioh_spi_select_chip
-+
-+<hr>
-+
-+*/
-+s8 ioh_spi_setup_transfer(struct spi_device *spi)
-+{
-+ u32 reg_spcr_val;
-+
-+ IOH_DEBUG("ioh_spi_setup_transfer SPBRR content =%x\n",
-+ ioh_spi_readreg(spi->master, IOH_SPI_SPBRR));
-+
-+ /*set baud rate */
-+ IOH_DEBUG("ioh_spi_setup_transfer :setting baud rate=%d\n",
-+ spi->max_speed_hz);
-+ ioh_spi_set_baud_rate(spi->master, spi->max_speed_hz);
-+
-+ /*set bits per word */
-+ IOH_DEBUG("ioh_spi_setup_transfer :setting bits_per_word=%d\n",
-+ spi->bits_per_word);
-+ ioh_spi_set_bits_per_word(spi->master, spi->bits_per_word);
-+
-+ IOH_DEBUG
-+ ("ioh_spi_setup_transfer SPBRR content after setting baud\
-+ rate & bits per word=%x\n",
-+ ioh_spi_readreg(spi->master, IOH_SPI_SPBRR));
-+
-+ reg_spcr_val = ioh_spi_readreg(spi->master, IOH_SPI_SPCR);
-+ IOH_DEBUG("ioh_spi_setup_transfer SPCR content = %x\n", reg_spcr_val);
-+
-+ /*set bit justification */
-+
-+ if ((spi->mode & SPI_LSB_FIRST) != 0) {
-+ /*LSB first */
-+ IOH_CLR_BITMSK(reg_spcr_val, SPCR_LSBF_BIT);
-+ IOH_DEBUG("ioh_spi_setup_transfer :setting LSBF bit to 0\n");
-+ } else {
-+ /*MSB first */
-+ IOH_SET_BITMSK(reg_spcr_val, SPCR_LSBF_BIT);
-+ IOH_DEBUG("ioh_spi_setup_transfer :setting LSBF bit to 1\n");
-+ }
-+
-+ /*set clock polarity */
-+ if ((spi->mode & SPI_CPOL) != 0) {
-+ IOH_SET_BITMSK(reg_spcr_val, SPCR_CPOL_BIT);
-+ IOH_DEBUG("ioh_spi_setup_transfer clock polarity = 1\n");
-+ } else {
-+ IOH_CLR_BITMSK(reg_spcr_val, SPCR_CPOL_BIT);
-+ IOH_DEBUG("ioh_spi_setup_transfer clock polarity = 0\n");
-+ }
-+
-+ /*set the clock phase */
-+ if ((spi->mode & SPI_CPHA) != 0) {
-+ IOH_SET_BITMSK(reg_spcr_val, SPCR_CPHA_BIT);
-+ IOH_DEBUG("ioh_spi_setup_transfer clock phase = 1\n");
-+ } else {
-+ IOH_CLR_BITMSK(reg_spcr_val, SPCR_CPHA_BIT);
-+ IOH_DEBUG("ioh_spi_setup_transfer clock phase = 0\n");
-+ }
-+
-+ /*write SPCR SPCR register */
-+ ioh_spi_writereg(spi->master, IOH_SPI_SPCR, reg_spcr_val);
-+
-+ IOH_DEBUG
-+ ("ioh_spi_setup_transfer SPCR content after setting LSB/MSB\
-+ and MODE= %x\n",
-+ reg_spcr_val);
-+
-+ /*Clear the FIFO by toggling FICLR to 1 and back to 0 */
-+ ioh_spi_clear_fifo(spi->master);
-+
-+ IOH_DEBUG("ioh_spi_setup_transfer Return=%d\n", IOH_SPI_SUCCESS);
-+
-+ return IOH_SPI_SUCCESS;
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_writereg(struct spi_master *master,int idx, u32 val)
-+
-+@remarks Performs register writes
-+
-+ The major tasks performed by this method are:
-+ - Obtain the SPI channel data structure from master.
-+ - Calculate the register address as offset + base address
-+ from SPI channel data structure.
-+ - Write the value specified by val to register the address calculated.
-+
-+@note This function is inline.
-+
-+@param master [@ref IN] Contains reference to struct spi_master
-+
-+@param idx [@ref IN] Contains register offset
-+
-+@param val [@ref IN] Contains value to be written to register
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_setup_transfer
-+ - ioh_spi_enable_interrupts
-+ - ioh_spi_disable_interrupts
-+ - ioh_spi_set_enable
-+ - ioh_spi_set_master_mode
-+ - ioh_spi_set_baud_rate
-+ - ioh_spi_set_bits_per_word
-+ - ioh_spi_reset
-+ - ioh_spi_set_threshold
-+ - ioh_spi_clear_fifo
-+ - ioh_spi_process_messages
-+
-+<hr>
-+
-+*/
-+inline void ioh_spi_writereg(struct spi_master *master, int idx, u32 val)
-+{
-+
-+ struct ioh_spi_data *pCtrlData = spi_master_get_devdata(master);
-+
-+ IOH_WRITE_LONG(val, (pCtrlData->IORemapAddress + idx));
-+
-+ IOH_DEBUG("ioh_spi_writereg Offset=%x\n", idx);
-+ IOH_DEBUG("ioh_spi_writereg Value=%x\n", val);
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_readreg(struct spi_master *master,int idx)
-+
-+@remarks Performs register reads
-+
-+ The major tasks performed by this method are:
-+ - Obtain the SPI channel data structure from master.
-+ - Calculate the register address as offset + base address
-+ from SPI channel data structure.
-+ - Read the content of the register at the address calculated.
-+
-+@note This function is inline
-+
-+@param master [@ref IN] Contains reference to struct spi_master
-+
-+@param idx [@ref IN] Contains register offset
-+
-+@retval u32
-+ The content of the register at offset idx
-+
-+@see
-+ - ioh_spi_setup_transfer
-+ - ioh_spi_enable_interrupts
-+ - ioh_spi_disable_interrupts
-+ - ioh_spi_set_enable
-+ - ioh_spi_set_master_mode
-+ - ioh_spi_set_baud_rate
-+ - ioh_spi_set_bits_per_word
-+ - ioh_spi_set_threshold
-+ - ioh_spi_clear_fifo
-+
-+<hr>
-+*/
-+inline u32 ioh_spi_readreg(struct spi_master *master, int idx)
-+{
-+ u32 reg_data;
-+
-+ struct ioh_spi_data *pCtrlData = spi_master_get_devdata(master);
-+
-+ IOH_DEBUG("ioh_spi_readreg Offset=%x\n", idx);
-+ reg_data = IOH_READ_LONG((pCtrlData->IORemapAddress + idx));
-+
-+ IOH_DEBUG("ioh_spi_readreg Content=%x\n", reg_data);
-+ return reg_data;
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_enable_interrupts (struct spi_master *master, u8 interrupt)
-+
-+@remarks Enables specified interrupts
-+
-+ The major tasks performed by this method are:
-+ - Read the content of SPCR.
-+ - Based on interrupt ,set corresponding bits in SPCR content.
-+ - Write the value back to SPCR.
-+
-+@note This function is invoked from @ref ioh_spi_process_messages before
-+ starting SPI data transfer.As of now only FI and RFI interrupts are
-+ used.
-+
-+@param master [@ref IN] Contains reference to struct spi_master
-+
-+@param interrupt [@ref IN] Interrups to be enabled.This parameter
-+ is a u8 value with five least significant bits representing
-+ each of the interrupts FI,RFI,TFI,ORI and MDFI.
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_process_messages
-+
-+<hr>
-+
-+*/
-+void ioh_spi_enable_interrupts(struct spi_master *master, u8 interrupt)
-+{
-+ u32 reg_val_spcr;
-+
-+ reg_val_spcr = ioh_spi_readreg(master, IOH_SPI_SPCR);
-+
-+ IOH_DEBUG("ioh_spi_enable_interrupts SPCR content=%x\n", reg_val_spcr);
-+
-+ if ((interrupt & IOH_SPI_RFI) != 0) {
-+ /*set RFIE bit in SPCR */
-+ IOH_DEBUG("setting RFI in ioh_spi_enable_interrupts\n");
-+ IOH_SET_BITMSK(reg_val_spcr, SPCR_RFIE_BIT);
-+ }
-+
-+ if ((interrupt & IOH_SPI_TFI) != 0) {
-+ /*set TFIE bit in SPCR */
-+ IOH_DEBUG("setting TFI in ioh_spi_enable_interrupts\n");
-+ IOH_SET_BITMSK(reg_val_spcr, SPCR_TFIE_BIT);
-+ }
-+
-+ if ((interrupt & IOH_SPI_FI) != 0) {
-+ /*set FIE bit in SPCR */
-+ IOH_DEBUG("setting FI in ioh_spi_enable_interrupts\n");
-+ IOH_SET_BITMSK(reg_val_spcr, SPCR_FIE_BIT);
-+ }
-+
-+ if ((interrupt & IOH_SPI_ORI) != 0) {
-+ /*set ORIE bit in SPCR */
-+ IOH_DEBUG("setting ORI in ioh_spi_enable_interrupts\n");
-+ IOH_SET_BITMSK(reg_val_spcr, SPCR_ORIE_BIT);
-+ }
-+
-+ if ((interrupt & IOH_SPI_MDFI) != 0) {
-+ /*set MODFIE bit in SPCR */
-+ IOH_DEBUG("setting MDFI in ioh_spi_enable_interrupts\n");
-+ IOH_SET_BITMSK(reg_val_spcr, SPCR_MDFIE_BIT);
-+ }
-+
-+ ioh_spi_writereg(master, IOH_SPI_SPCR, reg_val_spcr);
-+
-+ IOH_DEBUG
-+ ("ioh_spi_enable_interrupts SPCR content after enabling interrupt\
-+ =%x\n",
-+ reg_val_spcr);
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_disable_interrupts (struct spi_master *master, u8 interrupt)
-+
-+@remarks Disables specified interrupts
-+
-+ The major tasks performed by this method are:
-+ - Read the content of SPCR.
-+ - Based on interrupt ,clear corresponding bits in SPCR content.
-+ - Write the value back to SPCR.
-+
-+@param master [@ref IN] Contains reference to struct spi_master
-+
-+@param interrupt [@ref IN] Interrups to be disabled.This parameter
-+ is a u8 value with five least significant bits representing
-+ each of the interrupts FI,RFI,TFI,ORI and MDFI.
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_process_messages
-+ - ioh_spi_handler
-+ - ioh_spi_suspend
-+ - ioh_spi_free_resources
-+
-+<hr>
-+
-+*/
-+void ioh_spi_disable_interrupts(struct spi_master *master, u8 interrupt)
-+{
-+ u32 reg_val_spcr;
-+
-+ reg_val_spcr = ioh_spi_readreg(master, IOH_SPI_SPCR);
-+
-+ IOH_DEBUG("ioh_spi_disable_interrupts SPCR content =%x\n",
-+ reg_val_spcr);
-+
-+ if ((interrupt & IOH_SPI_RFI) != 0) {
-+ /*clear RFIE bit in SPCR */
-+ IOH_DEBUG("clearing RFI in ioh_spi_disable_interrupts\n");
-+ IOH_CLR_BITMSK(reg_val_spcr, SPCR_RFIE_BIT);
-+ }
-+
-+ if ((interrupt & IOH_SPI_TFI) != 0) {
-+ /*clear TFIE bit in SPCR */
-+ IOH_DEBUG("clearing TFI in ioh_spi_disable_interrupts\n");
-+ IOH_CLR_BITMSK(reg_val_spcr, SPCR_TFIE_BIT);
-+ }
-+
-+ if ((interrupt & IOH_SPI_FI) != 0) {
-+ /*clear FIE bit in SPCR */
-+ IOH_DEBUG("clearing FI in ioh_spi_disable_interrupts\n");
-+ IOH_CLR_BITMSK(reg_val_spcr, SPCR_FIE_BIT);
-+ }
-+
-+ if ((interrupt & IOH_SPI_ORI) != 0) {
-+ /*clear ORIE bit in SPCR */
-+ IOH_DEBUG("clearing ORI in ioh_spi_disable_interrupts\n");
-+ IOH_CLR_BITMSK(reg_val_spcr, SPCR_ORIE_BIT);
-+ }
-+
-+ if ((interrupt & IOH_SPI_MDFI) != 0) {
-+ /*clear MODFIE bit in SPCR */
-+ IOH_DEBUG("clearing MDFI in ioh_spi_disable_interrupts\n");
-+ IOH_CLR_BITMSK(reg_val_spcr, SPCR_MDFIE_BIT);
-+ }
-+
-+ ioh_spi_writereg(master, IOH_SPI_SPCR, reg_val_spcr);
-+
-+ IOH_DEBUG
-+ ("ioh_spi_disable_interrupts SPCR after disabling interrupts =%x\n",
-+ reg_val_spcr);
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_set_threshold(struct spi_device *spi, u32 threshold, u8 dir)
-+
-+@remarks Sets Tx/Rx FIFO thresholds
-+
-+The major tasks performed by this function are:
-+- Read the content of SPCR.
-+- If the dir is @ref IOH_SPI_RX ,set the Rx threshold bits in SPCR content.
-+- If the dir is @ref IOH_SPI_TX ,set the Tx threshold bits in SPCR content.
-+- Write back the value to SPCR.
-+
-+@note This function is invoked from ioh_spi_process_messages to set the Receive
-+threshold level.As of now, when the length of data to be transferred is greater
-+than FIFO depth of 16 bytes/words ,the Receive FIFO threshold is set at
-+ 8 bytes/words.
-+If the length of data to be transferred is less than FIFO depth,the Receive FIFO
-+threshold is set at 16 bytes/words.
-+
-+@param spi [@ref IN] Contains reference to struct spi_device
-+
-+@param threshold [@ref IN] Threshold value to be set
-+
-+@param dir [@ref IN] Rx or Tx threshold to be set
-+ - dir = @ref IOH_SPI_RX implies Receive FIFO threshold needs to be set.
-+ - dir = @ref IOH_SPI_TX implies Transmit FIFO threshold needs to be set.
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_process_messages
-+
-+<hr>
-+*/
-+void ioh_spi_set_threshold(struct spi_device *spi, u32 threshold, u8 dir)
-+{
-+ u32 reg_val_spcr;
-+
-+ reg_val_spcr = ioh_spi_readreg(spi->master, IOH_SPI_SPCR);
-+ IOH_DEBUG("ioh_spi_set_threshold SPCR before modifying =%x\n",
-+ reg_val_spcr);
-+ IOH_DEBUG("ioh_spi_set_threshold threshold=%d\n", (threshold + 1));
-+
-+ if (dir == IOH_SPI_RX) {
-+ IOH_DEBUG("ioh_spi_set_threshold setting Rx threshold\n");
-+ reg_val_spcr &= MASK_RFIC_SPCR_BITS;
-+ reg_val_spcr |= (threshold << SPCR_RFIC_FIELD);
-+ } else if (dir == IOH_SPI_TX) {
-+ IOH_DEBUG("ioh_spi_set_threshold setting Tx threshold\n");
-+ reg_val_spcr &= MASK_TFIC_SPCR_BITS;
-+ reg_val_spcr |= (threshold << SPCR_TFIC_FIELD);
-+ }
-+
-+ ioh_spi_writereg(spi->master, IOH_SPI_SPCR, reg_val_spcr);
-+
-+ IOH_DEBUG("ioh_spi_set_threshold SPCR after modifying =%x\n",
-+ reg_val_spcr);
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_reset(struct spi_master* master)
-+
-+@remarks Clears SPI registers
-+
-+ The major tasks performed by this method are:
-+ - Clear all R/W bits of SPCR.
-+ - Clear Receive and Transmit FIFOs by invoking @ref ioh_spi_clear_fifo
-+ - Clear all R/W bits of SPBRR.
-+ - Clear all interrupts in SPSR.
-+ - If the device has SRST [reset register],then instead of the
-+ above steps,first 1 is written to SRST to reset SPI and then
-+ 0 is written to SRST to clear reset.
-+
-+@note This function is invoked to bring the IOH SPI device to an
-+ initialized state.After this function is invoked all the SPI
-+ registers need to be configured again.
-+
-+@param master [@ref IN] Contains reference to struct spi_master
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_get_resources
-+ - ioh_spi_suspend
-+ - ioh_spi_resume
-+
-+<hr>
-+
-+*/
-+void ioh_spi_reset(struct spi_master *master)
-+{
-+#ifndef FPGA
-+ /*LSI*/
-+ /*write 1 to reset SPI */
-+ ioh_spi_writereg(master, IOH_SPI_SRST, 0x1);
-+ /*clear reset */
-+ ioh_spi_writereg(master, IOH_SPI_SRST, 0x0);
-+#else
-+ /*FPGA*/
-+ /*write 0 to SPCR */
-+ ioh_spi_writereg(master, IOH_SPI_SPCR, 0x0);
-+ IOH_DEBUG("ioh_spi_reset SPCR content after reset=%x\n",
-+ ioh_spi_readreg(master, IOH_SPI_SPCR));
-+ /*Clear the FIFO */
-+ ioh_spi_clear_fifo(master);
-+
-+ /*write 0 to SPBRR */
-+ ioh_spi_writereg(master, IOH_SPI_SPBRR, 0x0);
-+ IOH_DEBUG("ioh_spi_reset SPBRR content after reset=%x\n",
-+ ioh_spi_readreg(master, IOH_SPI_SPBRR));
-+
-+ /*clear interrupts in SPSR */
-+ ioh_spi_writereg(master, IOH_SPI_SPSR, SPSR_INT_BITS);
-+ IOH_DEBUG("ioh_spi_reset SPSR content after reset=%x\n",
-+ ioh_spi_readreg(master, IOH_SPI_SPSR));
-+#endif
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_set_baud_rate(struct spi_master* master,u32 speed_hz)
-+
-+@remarks Sets SPBR field in SPBRR
-+
-+ The major tasks performed by this method are:
-+ - Read the content of SPBRR register.
-+ - Calculate the value for SPBR field according to the baud rate.
-+ - Set the SPBR field using the calculated value.
-+ - Write the conetnt back to SPBRR.
-+
-+@note The SPBR value is calculated from the baud rate using the formula
-+ SPBR = clock frequency / baud rate.
-+
-+@param master [@ref IN] Contains reference to struct spi_master
-+
-+@param speed_hz [@ref IN] Baud rate to be set
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_setup_transfer
-+ - ioh_spi_process_messages
-+
-+<hr>
-+
-+*/
-+void ioh_spi_set_baud_rate(struct spi_master *master, u32 speed_hz)
-+{
-+ u32 nSpbr, reg_spbrr_val;
-+
-+ nSpbr = IOH_CLOCK_HZ / (speed_hz * 2);
-+
-+ /*if baud rate is less than we can support
-+ limit it */
-+
-+ if (nSpbr > IOH_SPI_MAX_SPBR)
-+ nSpbr = IOH_SPI_MAX_SPBR;
-+
-+
-+ reg_spbrr_val = ioh_spi_readreg(master, IOH_SPI_SPBRR);
-+
-+ IOH_DEBUG("ioh_spi_set_baud_rate SPBRR content=%x\n", reg_spbrr_val);
-+
-+ IOH_DEBUG("ioh_spi_set_baud_rate SPBR in SPBRR=%d\n", nSpbr);
-+
-+ /*clear SPBRR */
-+ reg_spbrr_val &= MASK_SPBRR_SPBR_BITS;
-+
-+ /*set the new value */
-+ reg_spbrr_val |= nSpbr;
-+
-+ /*write the new value */
-+ ioh_spi_writereg(master, IOH_SPI_SPBRR, reg_spbrr_val);
-+ IOH_DEBUG("ioh_spi_set_baud_rate SPBRR content after setting SPBR=%x\n",
-+ reg_spbrr_val);
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_set_bits_per_word(struct spi_master* master,u8 bits_per_word)
-+
-+@remarks Sets SIZE field in SPBRR
-+
-+ The major tasks performed by this method are:
-+ - Read the content of SPBRR register.
-+ - Set the SIZE field in SPBRR according to bits per word.
-+ - Write back the value to SPBRR.
-+
-+@note The allowed bits per word settings are 8 and 16.The SIZE bit in SPBRR is
-+ 0 denotes bits per word of 8 and SIZE bit 1 denotes bits per word of 16.
-+
-+@param master [@ref IN] Contains reference to struct spi_master
-+
-+@param bits_per_word [@ref IN] Bits per word for SPI transfer
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_setup_transfer
-+ - ioh_spi_process_messages
-+
-+<hr>
-+
-+*/
-+void ioh_spi_set_bits_per_word(struct spi_master *master, u8 bits_per_word)
-+{
-+ u32 reg_spbrr_val = ioh_spi_readreg(master, IOH_SPI_SPBRR);
-+ IOH_DEBUG("ioh_spi_set_bits_per_word SPBRR content=%x\n",
-+ reg_spbrr_val);
-+
-+ if (bits_per_word == IOH_SPI_8_BPW) {
-+ IOH_CLR_BITMSK(reg_spbrr_val, SPBRR_SIZE_BIT);
-+ IOH_DEBUG("ioh_spi_set_bits_per_word 8\n");
-+ } else {
-+ IOH_SET_BITMSK(reg_spbrr_val, SPBRR_SIZE_BIT);
-+ IOH_DEBUG("ioh_spi_set_bits_per_word 16\n");
-+ }
-+
-+ ioh_spi_writereg(master, IOH_SPI_SPBRR, reg_spbrr_val);
-+
-+ IOH_DEBUG
-+ ("ioh_spi_set_bits_per_word SPBRR after setting bits per word=%x\n",
-+ reg_spbrr_val);
-+}
-+
-+/*! @ingroup SPI_HALLayerAPI
-+
-+@fn ioh_spi_clear_fifo(struct spi_master *master)
-+
-+@remarks Clears the Transmit and Receive FIFOs
-+
-+ The major tasks performed by this method are:
-+ - Read the content of SPCR.
-+ - Set FICLR bit to 1.
-+ - Write back the content to SPCR.
-+ - Set the FICLR bit to 0.
-+ - Write back the content to SPCR.
-+
-+@param master [@ref IN] Contains reference to struct spi_master
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_setup_transfer
-+ - ioh_spi_process_messages
-+
-+<hr>
-+
-+*/
-+void ioh_spi_clear_fifo(struct spi_master *master)
-+{
-+ u32 reg_spcr_val = ioh_spi_readreg(master, IOH_SPI_SPCR);
-+
-+ IOH_SET_BITMSK(reg_spcr_val, SPCR_FICLR_BIT);
-+ ioh_spi_writereg(master, IOH_SPI_SPCR, reg_spcr_val);
-+ IOH_DEBUG("ioh_spi_clear_fifo SPCR content after setting FICLR = %x\n",
-+ reg_spcr_val);
-+
-+ IOH_CLR_BITMSK(reg_spcr_val, SPCR_FICLR_BIT);
-+ ioh_spi_writereg(master, IOH_SPI_SPCR, reg_spcr_val);
-+
-+ IOH_DEBUG
-+ ("ioh_spi_clear_fifo SPCR content after resetting FICLR = %x\n",
-+ reg_spcr_val);
-+}
-diff -urN linux-2.6.33-rc3/drivers/spi/pch_spi_hal.h topcliff-2.6.33-rc3/drivers/spi/pch_spi_hal.h
---- linux-2.6.33-rc3/drivers/spi/pch_spi_hal.h 1970-01-01 09:00:00.000000000 +0900
-+++ topcliff-2.6.33-rc3/drivers/spi/pch_spi_hal.h 2010-03-06 09:02:20.000000000 +0900
-@@ -0,0 +1,298 @@
-+/**
-+ * @file ioh_spi_hal.h
-+ *
-+ * @brief This header file contains macro definitions and function declarations
-+ * for HAL layer APIs.
-+ * @version 0.94
-+ *
-+ * @par
-+ * -- Copyright Notice --
-+ *
-+ * @par
-+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
-+ * All rights reserved.
-+ *
-+ * @par
-+ * 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.
-+ *
-+ * @par
-+ * -- End of Copyright Notice --
-+ */
-+#ifndef __IOH_SPI_HAL__
-+#define __IOH_SPI_HAL__
-+
-+/*Register offsets*/
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_SPCR
-+@brief SPCR register offset
-+*/
-+#define IOH_SPI_SPCR (0x00) /*SPI control register */
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_SPBRR
-+@brief SPBRR register offset
-+*/
-+#define IOH_SPI_SPBRR (0x04) /*SPI baud rate register */
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_SPSR
-+@brief SPSR register offset
-+*/
-+#define IOH_SPI_SPSR (0x08) /*SPI status register */
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_SPDWR
-+@brief SPDWR register offset
-+*/
-+#define IOH_SPI_SPDWR (0x0C) /*SPI write data register */
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_SPDRR
-+@brief SPDRR register offset
-+*/
-+#define IOH_SPI_SPDRR (0x10) /*SPI read data register */
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_SSNXCR
-+@brief SSNXCR register offset
-+*/
-+#define IOH_SPI_SSNXCR (0x18)/* SSN Expand Control Register */
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_SRST
-+@brief SRST register offset
-+*/
-+#define IOH_SPI_SRST (0x1C) /*SPI reset register */
-+
-+/* valid bits per word settings*/
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_8_BPW
-+@brief Macro to denote 8 Bits per word transfer
-+*/
-+#define IOH_SPI_8_BPW (8)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_16_BPW
-+@brief Macro to denote 16 Bits per word transfer
-+*/
-+#define IOH_SPI_16_BPW (16)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_SPSR_TFD
-+@brief Mask to obtaining TFD bits from SPSR
-+*/
-+#define IOH_SPI_SPSR_TFD (0x000007C0)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_SPSR_RFD
-+@brief Mask to obtaining RFD bits from SPSR
-+*/
-+#define IOH_SPI_SPSR_RFD (0x0000F800)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_READABLE(x)
-+@brief Macro to obtain number of bytes received in Rx FIFO
-+@note x is the content of SPSR register
-+*/
-+#define IOH_SPI_READABLE(x) (((x) & IOH_SPI_SPSR_RFD)>>11)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_WRITABLE(x)
-+@brief Macro to obtain number of bytes te be transmitted in Tx FIFO
-+@note x is the content of SPSR register
-+*/
-+#define IOH_SPI_WRITABLE(x) (((x) & IOH_SPI_SPSR_TFD)>>6)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_RX_THOLD
-+@brief Macro to denote Rx interrupt threshold
-+@note Currently set to interrupt when 8 bytes are received
-+*/
-+/*set to interrupt when 8 bytes have been received */
-+#define IOH_SPI_RX_THOLD (7)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_RX_THOLD_MAX
-+@brief Macro to denote Rx interrupt threshold when Rx FIFO is full
-+*/
-+/*set to interrupt when 16 bytes have been received */
-+#define IOH_SPI_RX_THOLD_MAX (15)
-+
-+/*direction for interrupts*/
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_RX
-+@brief Macro to indicate Receive
-+*/
-+#define IOH_SPI_RX (1)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_TX
-+@brief Macro to indicate Transmit
-+*/
-+#define IOH_SPI_TX (2)
-+
-+/*various interrupts*/
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_TFI
-+@brief Transmit interrupt
-+*/
-+#define IOH_SPI_TFI (0x1)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_RFI
-+@brief Receive interrupt
-+*/
-+#define IOH_SPI_RFI (0x2)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_FI
-+@brief Transfer complete interrupt
-+*/
-+#define IOH_SPI_FI (0x4)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_ORI
-+@brief Overflow interrupt
-+*/
-+#define IOH_SPI_ORI (0x8)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_MDFI
-+@brief Modefault interrupt
-+*/
-+#define IOH_SPI_MDFI (0x10)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_ALL
-+@brief Macro to denote all interrupts
-+*/
-+#define IOH_SPI_ALL \
-+ (IOH_SPI_TFI|IOH_SPI_RFI|IOH_SPI_FI|IOH_SPI_ORI|IOH_SPI_MDFI)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_MAX_BAUDRATE
-+@brief Macro to denote maximum possible baud rate in bits per second
-+*/
-+#define IOH_SPI_MAX_BAUDRATE (5000000)
-+
-+/*! @ingroup SPI_HALLayer
-+@def IOH_SPI_MAX_FIFO_DEPTH
-+@brief Macro to denote maximum FIFO depth(16)
-+*/
-+#define IOH_SPI_MAX_FIFO_DEPTH (16)
-+
-+/*status codes*/
-+
-+/*! @ingroup SPI_Global
-+@def IOH_SPI_SUCCESS
-+@brief Success status code
-+*/
-+#define IOH_SPI_SUCCESS (0)
-+
-+/*! @ingroup SPI_Global
-+@def IOH_SPI_FAIL
-+@brief Failure status code
-+*/
-+#define IOH_SPI_FAIL (-1)
-+
-+/* hal function prototypes */
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_setup_transfer(struct spi_device *spi)
-+@brief Configures the IOH SPI hardware for SPI transfer
-+*/
-+s8 ioh_spi_setup_transfer(struct spi_device *spi);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_set_enable(const struct spi_device *spi, u8 enable)
-+@brief Sets/Resets SPE bit in SPCR based on enable parameter
-+*/
-+void ioh_spi_set_enable(const struct spi_device *spi, u8 enable);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_set_master_mode( struct spi_master *master)
-+@brief Sets MSTR bit in SPCR
-+*/
-+void ioh_spi_set_master_mode(struct spi_master *master);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_writereg(struct spi_master *master,int idx, u32 val)
-+@brief Performs register writes
-+*/
-+inline void ioh_spi_writereg(struct spi_master *master, int idx, u32 val);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_readreg(struct spi_master *master,int idx)
-+@brief Performs register reads
-+*/
-+inline u32 ioh_spi_readreg(struct spi_master *master, int idx);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_handler (int irq, void* dev_id)
-+@brief The interrupt handler
-+*/
-+irqreturn_t ioh_spi_handler(int irq, void *dev_id);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_entcb (void (*ioh_spi_cb)( struct ioh_spi_data* ))
-+@brief Registers the Callback function
-+*/
-+void ioh_spi_entcb(void (*ioh_spi_cb) (struct ioh_spi_data *));
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_enable_interrupts (struct spi_master *master ,u8 interrupt)
-+@brief Enables specified interrupts in SPCR
-+*/
-+void ioh_spi_enable_interrupts(struct spi_master *master, u8 interrupt);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_disable_interrupts (struct spi_master *master ,u8 interrupt)
-+@brief Disables specified interrupts in SPCR
-+*/
-+void ioh_spi_disable_interrupts(struct spi_master *master, u8 interrupt);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_set_threshold(struct spi_device *spi,u32 threshold, u8 dir)
-+@brief Sets RFIC/TFIC fields in SPCR based on threshold and dir
-+*/
-+void ioh_spi_set_threshold(struct spi_device *spi, u32 threshold, u8 dir);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_reset(struct spi_master *master)
-+@brief Resets IOH SPI register settings
-+*/
-+void ioh_spi_reset(struct spi_master *master);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_set_baud_rate(struct spi_master *master,u32 speed_hz)
-+@brief Sets SPBR field in SPBRR
-+*/
-+void ioh_spi_set_baud_rate(struct spi_master *master, u32 speed_hz);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_set_bits_per_word(struct spi_master *master,u8 bits_per_word)
-+@brief Sets SIZE field in SPBRR
-+*/
-+void ioh_spi_set_bits_per_word(struct spi_master *master, u8 bits_per_word);
-+
-+/*! @ingroup SPI_HALLayerAPI
-+@fn ioh_spi_clear_fifo(struct spi_master *master)
-+@brief Clears Tx/Rx FIFOs by toggling FICLR bit in SPCR
-+*/
-+void ioh_spi_clear_fifo(struct spi_master *master);
-+#endif
-diff -urN linux-2.6.33-rc3/drivers/spi/pch_spi_main.c topcliff-2.6.33-rc3/drivers/spi/pch_spi_main.c
---- linux-2.6.33-rc3/drivers/spi/pch_spi_main.c 1970-01-01 09:00:00.000000000 +0900
-+++ topcliff-2.6.33-rc3/drivers/spi/pch_spi_main.c 2010-03-09 00:40:52.000000000 +0900
-@@ -0,0 +1,1323 @@
-+/**
-+ * @file ioh_spi_main.c
-+ *
-+ * @brief This file defines the SPI_InterfaceLayer APIs of the IOH SPI
-+ * controller
-+ * driver.
-+ *
-+ * @version 0.94
-+ *
-+ * @par
-+ * -- Copyright Notice --
-+ *
-+ * @par
-+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
-+ * All rights reserved.
-+ *
-+ * @par
-+ * 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.
-+ *
-+ * @par
-+ * -- End of Copyright Notice --
-+ */
-+
-+#include <linux/pci.h>
-+#include <linux/wait.h>
-+#include <linux/spi/spi.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include "pch_debug.h"
-+#include "pch_spi.h"
-+#include "pch_spi_hal.h"
-+
-+/*! @ingroup SPI_HALLayer
-+@def SSN_LOW
-+@brief SSNXCR register value to pull down SSN
-+*/
-+#define SSN_LOW (0x02U)
-+
-+/*! @ingroup SPI_HALLayer
-+@def SSN_NO_CONTROL
-+@brief SSNXCR register value to relinquish control over SSN
-+*/
-+#define SSN_NO_CONTROL (0x00U)
-+
-+/*function prototypes*/
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+@fn ioh_spi_deselect_chip(struct ioh_spi_data* pCtrlData)
-+@brief Clears the details of the current slave from the SPI channel
-+ data structure
-+*/
-+static inline void ioh_spi_deselect_chip(struct ioh_spi_data *pCtrlData);
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+@fn ioh_spi_select_chip(struct ioh_spi_data* pCtrlData,struct spi_device* pSpi)
-+@brief Update the slave device details in the SPI channel data structure
-+*/
-+static inline void ioh_spi_select_chip(struct ioh_spi_data *pCtrlData,
-+ struct spi_device *pSpi);
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+@fn ioh_spi_process_messages(struct work_struct* pWork)
-+@brief Work Queue handler to handle SPI data transfers
-+*/
-+static void ioh_spi_process_messages(struct work_struct *pWork);
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+
-+@fn ioh_spi_get_resources(struct ioh_spi_board_data* pBoardData)
-+
-+@remarks Acquires the resources needed by IOH SPI driver
-+
-+ The major tasks performed by this method are:
-+ - Initialize the spin lock of all SPI channels.
-+ - Initialize queue to hold pending SPI messages of all SPI channels.
-+ - Initialize wait queue head of all SPI channels.
-+ - Create the work structure for all SPI channels.
-+ - Create the work queues for all SPI channels.
-+ - Allocate PCI regions.
-+ - Get PCI memory mapped address and base addresses for all SPI channels.
-+ - Reset the IOH SPI hardware for all SPI channels.
-+ - Register the interrupt handler.
-+
-+@note This function is invoked by ioh_spi_probe to acquire
-+ the various resources needed by IOH SPI driver.If any of the actions
-+ performed by ioh_spi_get_resources fails,@ref ioh_spi_free_resources
-+ is invoked to perform the necessary cleanups.
-+
-+@param pBoardData [@ref INOUT]
-+ Contains the reference to struct ioh_spi_board_data
-+
-+@retval int
-+- @ref IOH_SPI_SUCCESS The function terminates normally after all
-+ required resources are acquired.
-+- -EBUSY create_singlethread_workqueue fails.
-+ pci_request_regions fails.
-+ request_irq fails.
-+- -EINVAL request_irq fails.
-+- -ENOSYS request_irq_fails.
-+- -ENOMEM pci_iomap_fails.
-+ request_irq fails.
-+
-+@see
-+ - ioh_spi_probe
-+
-+<hr>
-+*/
-+int ioh_spi_get_resources(struct ioh_spi_board_data *pBoardData)
-+{
-+ int i;
-+ long IORemapAddress;
-+ s32 iRetVal = IOH_SPI_SUCCESS;
-+ IOH_DEBUG("ioh_spi_get_resources ENTRY\n");
-+
-+ /*initialize resources */
-+
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ /*iniatize queue of pending messages */
-+ INIT_LIST_HEAD(&(pBoardData->pCtrlData[i]->Queue));
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources pCtrlData[i]->Queue initialized using"
-+ "INIT_LIST_HEAD\n");
-+
-+ /*initialize spin locks */
-+ spin_lock_init(&(pBoardData->pCtrlData[i]->Lock));
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources pCtrlData[i]->Lock initialized using"
-+ "spin_lock_init\n");
-+
-+ /*set channel status */
-+ pBoardData->pCtrlData[i]->Status = STATUS_RUNNING;
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources pCtrlData[i]->Status\
-+ = STATUS_RUNNING\n");
-+
-+ /*initialize work structure */
-+ INIT_WORK(&(pBoardData->pCtrlData[i]->Work),
-+ ioh_spi_process_messages);
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources pCtrlData[i]->Work initialized\
-+ using INIT_WORK\n");
-+
-+ /*initialize wait queues */
-+ init_waitqueue_head(&(pBoardData->pCtrlData[i]->Wait));
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources pCtrlData[i]->Wait initialized\
-+ using init_waitqueue_head\n");
-+ }
-+
-+ do {
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ /*create workqueue */
-+ pBoardData->pCtrlData[i]->pWorkQueue =
-+ create_singlethread_workqueue(DRIVER_NAME);
-+
-+ if ((pBoardData->pCtrlData[i]->pWorkQueue) == NULL) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_get_resources create_singlet\
-+ hread_workqueue failed\n");
-+ iRetVal = -EBUSY;
-+ break;
-+ }
-+ }
-+
-+ if (iRetVal != 0)
-+ break;
-+
-+
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources create_singlethread_workqueue\
-+ success\n");
-+ iRetVal = pci_request_regions(pBoardData->pDev, DRIVER_NAME);
-+ if (iRetVal != 0) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_get_resources request_region failed\n");
-+ break;
-+ }
-+
-+ IOH_DEBUG("ioh_spi_get_resources request_region returned=%d\n",
-+ iRetVal);
-+
-+ pBoardData->bRegionRequested = true;
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources pCtrlData->bRegionRequested = true\n");
-+
-+ /* Wipro 1/13/2010 Use Mem BAR */
-+ IORemapAddress =
-+ (unsigned long)pci_iomap(pBoardData->pDev, 1, 0);
-+
-+ if (IORemapAddress == 0) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_get_resources pci_iomap failed\n");
-+ iRetVal = -ENOMEM;
-+ break;
-+ }
-+
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources pci_iomap success PCI Base\
-+ address=%x\n",
-+ (IORemapAddress));
-+
-+ /*calculate base address for all channels */
-+
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ pBoardData->pCtrlData[i]->IORemapAddress =
-+ IORemapAddress + (IOH_SPI_ADDRESS_SIZE * i);
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources Base address for\
-+ channel %d= %x\n",
-+ i, (pBoardData->pCtrlData[i]->IORemapAddress));
-+ }
-+
-+ /*reset IOH SPI h/w */
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ ioh_spi_reset(pBoardData->pCtrlData[i]->pMaster);
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources ioh_spi_reset invoked\
-+ successfully \n");
-+ }
-+
-+ /*register IRQ */
-+ iRetVal = request_irq(pBoardData->pDev->irq, ioh_spi_handler,
-+ IRQF_SHARED, DRIVER_NAME,
-+ (void *)pBoardData);
-+ if (iRetVal != 0) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_get_resources request_irq failed\n");
-+ break;
-+ }
-+
-+ IOH_DEBUG("ioh_spi_get_resources request_irq returned=%d\n",
-+ iRetVal);
-+
-+ pBoardData->bIrqRegistered = true;
-+ IOH_DEBUG
-+ ("ioh_spi_get_resources pCtrlData->bIrqRegistered=true\n");
-+ } while (0);
-+
-+ if (iRetVal != IOH_SPI_SUCCESS) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_get_resources FAIL:invoking\
-+ ioh_spi_free_resources\n");
-+ ioh_spi_free_resources(pBoardData);
-+ }
-+
-+ IOH_DEBUG("ioh_spi_get_resources Return=%d\n", iRetVal);
-+
-+ return iRetVal;
-+}
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+
-+@fn ioh_spi_free_resources(struct ioh_spi_board_data* pBoardData)
-+
-+@remarks Frees the resources acquired by IOH SPI driver
-+
-+ The main tasks performed by this method are:
-+ - Destroy the workqueus created for all SPI channels.
-+ - Disables interrupts and unregisters the interrupt handler.
-+ - Unmaps the PCI base address.
-+ - Releases PCI regions.
-+
-+@note This function is invoked from ioh_spi_remove when the SPI device is
-+ being removed from the system or when the IOH SPI driver is being
-+ unloaded from the system using "rmmod" command.
-+
-+@param pBoardData [@ref INOUT] Contains the reference to struct
-+ ioh_spi_board_data
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_remove
-+
-+<hr>
-+*/
-+void ioh_spi_free_resources(struct ioh_spi_board_data *pBoardData)
-+{
-+ int i;
-+
-+ IOH_DEBUG("ioh_spi_free_resources ENTRY\n");
-+
-+ /*free workqueue */
-+
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ if (pBoardData->pCtrlData[i]->pWorkQueue != NULL) {
-+ destroy_workqueue(pBoardData->pCtrlData[i]->pWorkQueue);
-+ pBoardData->pCtrlData[i]->pWorkQueue = NULL;
-+ IOH_DEBUG
-+ ("ioh_spi_free_resources destroy_workqueue invoked\
-+ successfully\n");
-+ }
-+ }
-+
-+ /*disable interrupts & free IRQ */
-+ if (pBoardData->bIrqRegistered == true) {
-+ /* disable interrupts */
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ ioh_spi_disable_interrupts(pBoardData->pCtrlData[i]->
-+ pMaster, IOH_SPI_ALL);
-+ IOH_DEBUG
-+ ("ioh_spi_free_resources ioh_spi_disable_interrupts\
-+ invoked successfully\n");
-+ }
-+
-+ /*free IRQ */
-+ free_irq(pBoardData->pDev->irq, (void *)pBoardData);
-+
-+ IOH_DEBUG
-+ ("ioh_spi_free_resources free_irq invoked successfully\n");
-+
-+ pBoardData->bIrqRegistered = false;
-+ }
-+
-+ /*unmap PCI base address */
-+ if ((pBoardData->pCtrlData[0]->IORemapAddress) != 0) {
-+ pci_iounmap(pBoardData->pDev,
-+ (void *)(pBoardData->pCtrlData[0]->IORemapAddress));
-+
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++)
-+ pBoardData->pCtrlData[i]->IORemapAddress = 0;
-+
-+
-+ IOH_DEBUG
-+ ("ioh_spi_free_resources pci_iounmap invoked\
-+ successfully\n");
-+ }
-+
-+ /*release PCI region */
-+ if (pBoardData->bRegionRequested == true) {
-+ pci_release_regions(pBoardData->pDev);
-+ IOH_DEBUG
-+ ("ioh_spi_free_resources pci_release_regions invoked\
-+ successfully\n");
-+ pBoardData->bRegionRequested = false;
-+ }
-+}
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+
-+@fn ioh_spi_process_messages(struct work_struct* pWork)
-+
-+@remarks Work Queue handler to handle SPI data transfers
-+
-+The main tasks performed by this method are:
-+- If system is suspended,then flush the queue of pending transfers and return.
-+- Retrieve the SPI message to be processed from the queue of pending messages.
-+- Invoke @ref ioh_spi_select_chip to configure the SPI channel.
-+- Retrieve the 1st or the subsequent transfer structure from SPI message
-+ structure.
-+- Update baud rate and bits per word,if user has specified new values.
-+- Allocate memory for Transmit and Receive buffers.
-+- Copy transmit data from transfer structure to Transmit buffer.
-+- Pull down SSN by writing 0x2 to SSNXCR register.
-+- Write transmit data to Transmit FIFO.
-+- Enable required interrupts.
-+- Enable SPI transfer by invoking @ref ioh_spi_set_enable.
-+- Wait till SPI data transfer is completed.
-+- Relinquish control over SSN by writing 0x0 to SSNXCR register.
-+- Disable SPI transfer by invoking @ref ioh_spi_set_enable.
-+- Clear Transmit & Receive FIFOs by invoking @ref ioh_spi_clear_fifo.
-+- Copy received data from Receive buffer to transfer structure.
-+- Free memory allocated for Transmit and Receive buffers.
-+- Update data count in transfer structure.
-+- If the SPI message has any more transfers , process them same as above.
-+- If system is suspended,then flush the queue of pending transfers and return.
-+- Again schedule the work queue haandler to run if there are pending messages in
-+queue of pending messages.
-+
-+@note Work Queue handler is scheduled by @ref ioh_spi_transfer after
-+the SPI message to be processed is pushed into the queue of pending
-+transfers.This function will write the first set of data to Tx FIFO and sleeps
-+till all SPI data transfer is over.The data transfer is handled by
-+the interrupt handler ioh_spi_handler function.
-+
-+@param pWork [@ref IN] contains reference to struct work_struct
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_transfer
-+
-+<hr>
-+*/
-+static void ioh_spi_process_messages(struct work_struct *pWork)
-+{
-+ int j;
-+ u32 nWrites;
-+
-+ struct spi_message *pMsg;
-+ int bMemFail, size;
-+ int bpw;
-+
-+ struct ioh_spi_data *pCtrlData =
-+ container_of(pWork, struct ioh_spi_data, Work);
-+ IOH_DEBUG("ioh_spi_process_messages pCtrlData initialized\n");
-+
-+ spin_lock(&pCtrlData->Lock);
-+
-+ /*check if suspend has been initiated;if yes flush queue */
-+
-+ if ((pCtrlData->pBoardData->bSuspended == true)
-+ || (pCtrlData->Status == STATUS_EXITING)) {
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages suspend/remove initiated,\
-+ flushing queue\n");
-+ list_for_each_entry(pMsg, pCtrlData->Queue.next, queue) {
-+ pMsg->status = -EIO;
-+
-+ if (pMsg->complete != 0)
-+ pMsg->complete(pMsg->context);
-+
-+
-+ /*delete from queue */
-+ list_del_init(&pMsg->queue);
-+ }
-+
-+ spin_unlock(&pCtrlData->Lock);
-+ } else {
-+ pCtrlData->bCurrent_msg_processing = true;
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages set pCtrlData->\
-+ bCurrent_msg_processing"
-+ "= true\n");
-+
-+ /*Get the message from the queue and delete it from there. */
-+ pCtrlData->pCurMsg =
-+ list_entry(pCtrlData->Queue.next, struct spi_message,
-+ queue);
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages :Got new message from queue \n");
-+ list_del_init(&pCtrlData->pCurMsg->queue);
-+
-+ pCtrlData->pCurMsg->status = 0;
-+
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages :Invoking ioh_spi_select_chip\n");
-+ ioh_spi_select_chip(pCtrlData, pCtrlData->pCurMsg->spi);
-+
-+ spin_unlock(&pCtrlData->Lock);
-+
-+ do {
-+ /*If we are already processing a message get the next
-+ transfer
-+ structure from the message otherwise retrieve the
-+ 1st transfer
-+ request from the message. */
-+ spin_lock(&pCtrlData->Lock);
-+
-+ if (pCtrlData->pCurTransfer == NULL) {
-+ pCtrlData->pCurTransfer =
-+ list_entry(pCtrlData->pCurMsg->transfers.
-+ next, struct spi_transfer,
-+ transfer_list);
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages :Getting 1st\
-+ transfer structure"
-+ "for this message\n");
-+ } else {
-+ pCtrlData->pCurTransfer =
-+ list_entry(pCtrlData->pCurTransfer->
-+ transfer_list.next,
-+ struct spi_transfer,
-+ transfer_list);
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages :Getting next\
-+ transfer structure"
-+ "for this message\n");
-+ }
-+
-+ spin_unlock(&pCtrlData->Lock);
-+
-+ /*set baud rate if needed */
-+
-+ if (pCtrlData->pCurTransfer->speed_hz) {
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:setting\
-+ baud rate\n");
-+ ioh_spi_set_baud_rate(pCtrlData->pMaster,
-+ (pCtrlData->pCurTransfer->
-+ speed_hz));
-+ }
-+
-+ /*set bits per word if needed */
-+ if ((pCtrlData->pCurTransfer->bits_per_word) &&
-+ ((pCtrlData->pCurMsg->spi->bits_per_word) !=
-+ (pCtrlData->pCurTransfer->bits_per_word))) {
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:setting bits\
-+ per word\n");
-+ ioh_spi_set_bits_per_word(pCtrlData->pMaster,
-+ (pCtrlData->
-+ pCurTransfer->
-+ bits_per_word));
-+ bpw = pCtrlData->pCurTransfer->bits_per_word;
-+ } else {
-+ bpw = pCtrlData->pCurMsg->spi->bits_per_word;
-+ }
-+
-+ /*reset Tx/Rx index */
-+ pCtrlData->TxIndex = 0;
-+
-+ pCtrlData->RxIndex = 0;
-+
-+ if (IOH_SPI_8_BPW == bpw) {
-+ /*8 bits per word */
-+ pCtrlData->lengthInBpw =
-+ pCtrlData->pCurTransfer->len;
-+ } else {
-+ /*16 bits per word */
-+ pCtrlData->lengthInBpw =
-+ (pCtrlData->pCurTransfer->len) / 2;
-+ }
-+
-+ bMemFail = false;
-+
-+ /*find alloc size */
-+ size =
-+ (pCtrlData->pCurTransfer->len) *
-+ (sizeof(*(pCtrlData->pU16TxBuffer)));
-+ /*allocate memory for pU16TxBuffer & pU16RxBuffer */
-+ pCtrlData->pU16TxBuffer =
-+/* (u16 *) kzalloc(size, GFP_KERNEL);*/
-+ kzalloc(size, GFP_KERNEL);
-+ if (pCtrlData->pU16TxBuffer != NULL) {
-+ pCtrlData->pU16RxBuffer =
-+/* (u16 *) kzalloc(size, GFP_KERNEL);*/
-+ kzalloc(size, GFP_KERNEL);
-+ if (pCtrlData->pU16RxBuffer == NULL) {
-+ bMemFail = true;
-+ kfree(pCtrlData->pU16TxBuffer);
-+ }
-+ } else {
-+ bMemFail = true;
-+ }
-+
-+ if (bMemFail) {
-+ /*flush queue and set status of all transfers
-+ to -ENOMEM */
-+ IOH_LOG(KERN_ERR,
-+ "Kzalloc fail in\
-+ ioh_spi_process_messages\n");
-+ list_for_each_entry(pMsg, pCtrlData->Queue.next,
-+ queue) {
-+ pMsg->status = -ENOMEM;
-+
-+ if (pMsg->complete != 0)
-+ pMsg->complete(pMsg->context);
-+
-+
-+ /*delete from queue */
-+ list_del_init(&pMsg->queue);
-+ }
-+
-+ return;
-+ }
-+
-+ /*copy Tx Data */
-+ if ((pCtrlData->pCurTransfer->tx_buf) != NULL) {
-+ for (j = 0; j < (pCtrlData->lengthInBpw); j++) {
-+ if (IOH_SPI_8_BPW == bpw) {
-+ pCtrlData->pU16TxBuffer[j] =
-+ (((u8 *) (pCtrlData->
-+ pCurTransfer->
-+ tx_buf))[j]);
-+ IOH_DEBUG
-+ ("xmt data in\
-+ ioh_spi_process_messages=%x\n",
-+ (pCtrlData->
-+ pU16TxBuffer[j]));
-+ } else {
-+ pCtrlData->pU16TxBuffer[j] =
-+ ((u16 *) (pCtrlData->
-+ pCurTransfer->
-+ tx_buf))[j];
-+ IOH_DEBUG
-+ ("xmt data ioh_spi_pro\
-+ cess_messages%x\n",
-+ (pCtrlData->
-+ pU16TxBuffer[j]));
-+ }
-+ }
-+ }
-+
-+ /*if len greater than IOH_SPI_MAX_FIFO_DEPTH,
-+ write 16,else len bytes */
-+ if ((pCtrlData->lengthInBpw) > IOH_SPI_MAX_FIFO_DEPTH)
-+ nWrites = IOH_SPI_MAX_FIFO_DEPTH;
-+ else
-+ nWrites = (pCtrlData->lengthInBpw);
-+
-+
-+#ifndef FPGA
-+ /*LSI*/
-+ IOH_DEBUG
-+ ("\nioh_spi_process_messages:Pulling down SSN low\
-+ - writing 0x2 to SSNXCR\n");
-+ ioh_spi_writereg(pCtrlData->pMaster, IOH_SPI_SSNXCR,
-+ SSN_LOW);
-+#endif
-+ IOH_DEBUG
-+ ("\nioh_spi_process_messages:Writing %u items\n",
-+ nWrites);
-+
-+ for (j = 0; j < nWrites; j++) {
-+ ioh_spi_writereg(pCtrlData->pMaster,
-+ IOH_SPI_SPDWR,
-+ pCtrlData->pU16TxBuffer[j]);
-+ }
-+
-+ /*update TxIndex */
-+ pCtrlData->TxIndex = j;
-+
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:enabling interrupts\n");
-+
-+ /*reset transfer complete flag */
-+ pCtrlData->bTransferComplete = false;
-+
-+ pCtrlData->bTransferActive = true;
-+
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages set pCtrlData->\
-+ bTransferActive = true\n");
-+
-+ /*enable interrupts */
-+ if ((pCtrlData->lengthInBpw) > IOH_SPI_MAX_FIFO_DEPTH) {
-+ /*set receive threhold to IOH_SPI_RX_THOLD */
-+ ioh_spi_set_threshold(pCtrlData->pCurrentChip,
-+ IOH_SPI_RX_THOLD,
-+ IOH_SPI_RX);
-+ /*enable FI and RFI interrupts */
-+ ioh_spi_enable_interrupts(pCtrlData->pMaster,
-+ IOH_SPI_RFI |
-+ IOH_SPI_FI);
-+ } else {
-+ /*set receive threhold to maximum */
-+ ioh_spi_set_threshold(pCtrlData->pCurrentChip,
-+ IOH_SPI_RX_THOLD_MAX,
-+ IOH_SPI_RX);
-+ /*enable FI interrupt */
-+ ioh_spi_enable_interrupts(pCtrlData->pMaster,
-+ IOH_SPI_FI);
-+ }
-+
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:invoking\
-+ ioh_spi_set_enable to enable SPI\n");
-+
-+ ioh_spi_set_enable((pCtrlData->pCurrentChip), true);
-+
-+ /*Wait until the transfer completes; go to sleep
-+ after initiating the transfer. */
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:waiting for transfer\
-+ to get over\n");
-+
-+ wait_event_interruptible(pCtrlData->Wait,
-+ false !=
-+ pCtrlData->bTransferComplete);
-+#ifndef FPGA
-+ /*LSI*/
-+ ioh_spi_writereg(pCtrlData->pMaster, IOH_SPI_SSNXCR,
-+ SSN_NO_CONTROL);
-+ IOH_DEBUG
-+ ("\n ioh_spi_process_messages:no more control over\
-+ SSN-writing 0x0 to SSNXCR");
-+#endif
-+ IOH_DEBUG("ioh_spi_process_messages:transmit over\n");
-+
-+ pCtrlData->bTransferActive = false;
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages set pCtrlData->\
-+ bTransferActive = false\n");
-+
-+ /*clear all interrupts */
-+ ioh_spi_writereg(pCtrlData->pMaster, IOH_SPI_SPSR,
-+ (ioh_spi_readreg
-+ (pCtrlData->pMaster, IOH_SPI_SPSR)));
-+ /*disable interrupts */
-+ ioh_spi_disable_interrupts(pCtrlData->pMaster,
-+ IOH_SPI_ALL);
-+
-+ /*Disable SPI transfer */
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:invoking\
-+ ioh_spi_set_enable to disable"
-+ "spi transfer\n");
-+ ioh_spi_set_enable((pCtrlData->pCurrentChip), false);
-+
-+ /*clear FIFO */
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:invoking\
-+ ioh_spi_clear_fifo to "
-+ "clear fifo\n");
-+ ioh_spi_clear_fifo(pCtrlData->pMaster);
-+
-+ /*copy Rx Data */
-+
-+ if ((pCtrlData->pCurTransfer->rx_buf) != NULL) {
-+ for (j = 0; j < (pCtrlData->lengthInBpw); j++) {
-+ if (IOH_SPI_8_BPW == bpw) {
-+ ((u8 *) (pCtrlData->
-+ pCurTransfer->
-+ rx_buf))[j] =
-+ (u8) ((pCtrlData->
-+ pU16RxBuffer[j]) &
-+ 0xFF);
-+
-+ IOH_DEBUG
-+ ("rcv data in ioh_spi_proc\
-+ ess_messages=%x\n",
-+ (pCtrlData->
-+ pU16RxBuffer[j]));
-+
-+ } else {
-+ ((u16 *) (pCtrlData->
-+ pCurTransfer->
-+ rx_buf))[j] =
-+ (u16) (pCtrlData->
-+ pU16RxBuffer[j]);
-+ IOH_DEBUG
-+ ("rcv data in ioh_spi_proce\
-+ ss_messages=%x\n",
-+ (pCtrlData->
-+ pU16RxBuffer[j]));
-+ }
-+ }
-+ }
-+
-+ /*free memory */
-+ kfree(pCtrlData->pU16RxBuffer);
-+ pCtrlData->pU16RxBuffer = NULL;
-+
-+
-+ kfree(pCtrlData->pU16TxBuffer);
-+ pCtrlData->pU16TxBuffer = NULL;
-+
-+
-+ /*increment message count */
-+ pCtrlData->pCurMsg->actual_length +=
-+ pCtrlData->pCurTransfer->len;
-+
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:pCtrlData->pCurMsg->\
-+ actual_length=%d\n",
-+ pCtrlData->pCurMsg->actual_length);
-+
-+ /*check for delay */
-+ if (pCtrlData->pCurTransfer->delay_usecs) {
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:delay in usec=%d\n",
-+ pCtrlData->pCurTransfer->delay_usecs);
-+ udelay(pCtrlData->pCurTransfer->delay_usecs);
-+ }
-+
-+ spin_lock(&pCtrlData->Lock);
-+
-+ /*No more transfer in this message. */
-+
-+ if ((pCtrlData->pCurTransfer->transfer_list.next) ==
-+ &(pCtrlData->pCurMsg->transfers)) {
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:no more\
-+ transfers in this message\n");
-+ /*Invoke complete callback
-+ [To the spi core..indicating
-+ end of transfer] */
-+ pCtrlData->pCurMsg->status = 0;
-+
-+ if ((pCtrlData->pCurMsg->complete) != 0) {
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:Invoking\
-+ callback of SPI core\n");
-+ pCtrlData->pCurMsg->complete(pCtrlData->
-+ pCurMsg->
-+ context);
-+ }
-+
-+ /*update status in global variable */
-+ pCtrlData->bCurrent_msg_processing = false;
-+
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:pCtrlData->\
-+ bCurrent_msg_processing"
-+ "set to false\n");
-+
-+ pCtrlData->pCurMsg = NULL;
-+
-+ pCtrlData->pCurTransfer = NULL;
-+
-+ /*check if we have items in list and not
-+ suspending */
-+ /*return 1 if list empty */
-+ if ((list_empty(&pCtrlData->Queue) == 0) &&
-+ (pCtrlData->pBoardData->bSuspended == false)
-+ && (pCtrlData->Status != STATUS_EXITING)) {
-+ /*We have some more work to do
-+ (either there is more transfer
-+ requests in the current message or
-+ there are more messages) */
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages:we\
-+ have pending messages"
-+ "-Invoking queue_work\n");
-+ queue_work(pCtrlData->pWorkQueue,
-+ &pCtrlData->Work);
-+ }
-+
-+ /*check if suspend has been initiated;if yes
-+ flush queue */
-+ else if ((pCtrlData->pBoardData->bSuspended ==
-+ true)
-+ || (pCtrlData->Status ==
-+ STATUS_EXITING)) {
-+ IOH_DEBUG
-+ ("ioh_spi_process_messages\
-+ suspend/remove initiated,"
-+ "flushing queue\n");
-+ list_for_each_entry(pMsg,
-+ pCtrlData->Queue.
-+ next, queue) {
-+ pMsg->status = -EIO;
-+
-+ if (pMsg->complete != 0) {
-+ pMsg->complete(pMsg->
-+ context);
-+ }
-+
-+ /*delete from queue */
-+ list_del_init(&pMsg->queue);
-+ }
-+ }
-+ }
-+
-+ spin_unlock(&pCtrlData->Lock);
-+
-+ } while ((pCtrlData->pCurTransfer) != NULL);
-+ }
-+}
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+
-+@fn ioh_spi_select_chip(struct ioh_spi_data* pCtrlData,struct spi_device* pSpi)
-+
-+@remarks Update the SPI device details in the SPI channel data structure
-+
-+The main tasks performed by this method are:
-+- Check whether the active SPI device is different from the device to
-+ which the previous data transfer occured.
-+- If yes invoke @ref ioh_spi_deselect_chip to clear details of old device
-+ from pCtrlData.
-+- Update the details of the new device in pCtrlData
-+- Invoke @ref ioh_spi_setup_transfer to configure the SPI channel.
-+
-+@note This function is invoked by @ref ioh_spi_process_messages before
-+ processing
-+ each SPI message.
-+
-+@param pCtrlData [@ref INOUT] contains reference to struct ioh_spi_data
-+
-+@param pSpi [@ref IN] contains reference to struct spi_device
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_process_messages
-+
-+<hr>
-+*/
-+static inline void ioh_spi_select_chip(struct ioh_spi_data *pCtrlData,
-+ struct spi_device *pSpi)
-+{
-+ if ((pCtrlData->pCurrentChip) != NULL) {
-+ if ((pSpi->chip_select) != (pCtrlData->nCurrentChip)) {
-+ IOH_DEBUG
-+ ("ioh_spi_select_chip : different slave-Invoking"
-+ "ioh_spi_deselect_chip\n");
-+ ioh_spi_deselect_chip(pCtrlData);
-+ }
-+ }
-+
-+ pCtrlData->pCurrentChip = pSpi;
-+
-+ pCtrlData->nCurrentChip = pCtrlData->pCurrentChip->chip_select;
-+
-+ IOH_DEBUG("ioh_spi_select_chip :Invoking ioh_spi_setup_transfer\n");
-+ ioh_spi_setup_transfer(pSpi);
-+}
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+
-+@fn ioh_spi_deselect_chip(struct ioh_spi_data* pCtrlData)
-+
-+@remarks Clear the SPI device details from the SPI channel data structure
-+
-+ The main tasks performed by this method are:
-+ - Clear the details of SPI device from SPI channel data structure.
-+
-+@note This function is invoked from @ref ioh_spi_select_chip
-+
-+@param pCtrlData [@ref INOUT] Contains reference to struct ioh_spi_data
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_select_chip
-+
-+<hr>
-+*/
-+static inline void ioh_spi_deselect_chip(struct ioh_spi_data *pCtrlData)
-+{
-+ if (pCtrlData->pCurrentChip != NULL) {
-+ IOH_DEBUG
-+ ("ioh_spi_deselect_chip :clearing pCurrentChip data\n");
-+ pCtrlData->pCurrentChip = NULL;
-+ }
-+}
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+
-+@fn ioh_spi_check_request_pending(struct ioh_spi_board_data* pBoardData)
-+
-+@remarks Checks for any pending SPI transfer request in the queue of
-+ pending transfers
-+
-+ The main tasks performed by this method are:
-+ - If the message queue is empty return IOH_SPI_SUCCESS.
-+ - Sleep for 100ms and again check if message queue is empty,if yes
-+ return IOH_SPI_SUCCESS.
-+ - Repeat 500 times.
-+ - If queue is still not empty return -EBUSY.
-+
-+@note This function is invoked by @ref ioh_spi_remove
-+
-+@param pBoardData [@ref INOUT] Contains reference to struct
-+ ioh_spi_board_data
-+
-+@retval int
-+ - @ref IOH_SPI_SUCCESS Message queue is empty
-+ - -EBUSY Queue is not empty
-+
-+@see
-+ - ioh_spi_remove
-+
-+<hr>
-+*/
-+int ioh_spi_check_request_pending(struct ioh_spi_board_data *pBoardData)
-+{
-+ int i;
-+ int iStatus = IOH_SPI_SUCCESS;
-+ u16 count;
-+
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ count = 500;
-+ spin_lock(&(pBoardData->pCtrlData[i]->Lock));
-+ pBoardData->pCtrlData[i]->Status = STATUS_EXITING;
-+
-+ while ((list_empty(&(pBoardData->pCtrlData[i]->Queue)) == 0) &&
-+ (--count)) {
-+ IOH_DEBUG
-+ ("ioh_spi_check_request_pending :Queue not empty\n");
-+ spin_unlock(&(pBoardData->pCtrlData[i]->Lock));
-+ msleep(IOH_SPI_SLEEP_TIME);
-+ spin_lock(&(pBoardData->pCtrlData[i]->Lock));
-+ }
-+
-+ spin_unlock(&(pBoardData->pCtrlData[i]->Lock));
-+
-+ if (count) {
-+ IOH_DEBUG
-+ ("ioh_spi_check_request_pending :Queue empty\n");
-+ } else {
-+ iStatus = -EBUSY;
-+ }
-+ }
-+
-+ IOH_DEBUG("ioh_spi_check_request_pending : EXIT=%d\n", iStatus);
-+
-+ return iStatus;
-+}
-+
-+/*! @ingroup SPI_InterfaceLayerAPI
-+
-+@fn int ioh_spi_setup(struct spi_device* pSpi)
-+
-+@remarks Validates the SPI device configuration paramters specified by user
-+
-+The main tasks performed by this method are:
-+- Validate the bits per word paramter (should be either 8 or 16).
-+- Validate the maximum baud rate parameter (should not be greater than 5Mbps).
-+
-+@note This function is registered with the SPI core as the setup routine of
-+IOH SPI controller driver.This function is invoked by the kernel SPI
-+component when user invokes any of spidev's IOCTLs to configure the
-+SPI device setting.In this function no hardware settings are modified
-+as this can affect any ongoing SPI data transfers.So the setting passed
-+by the user is validated and the function returns.Hardware settings are
-+updated in the function @ref ioh_spi_setup_transfer, which is invoked from
-+@ref ioh_spi_process_messages before initiating a SPI data transfer.
-+
-+@param pSpi [@ref IN] Contains reference to structure spi_device
-+
-+@retval int
-+ - IOH_SPI_SUCCESS All paramters are valid
-+ - -EINVAL Any of the paramter is invalid
-+
-+@see
-+ - ioh_spi_probe
-+
-+<hr>
-+*/
-+int ioh_spi_setup(struct spi_device *pSpi)
-+{
-+ int iRetVal = IOH_SPI_SUCCESS;
-+
-+ /*check bits per word */
-+
-+ if ((pSpi->bits_per_word) == 0) {
-+ pSpi->bits_per_word = IOH_SPI_8_BPW;
-+ IOH_DEBUG("ioh_spi_setup 8 bits per word \n");
-+ }
-+
-+ if (((pSpi->bits_per_word) != IOH_SPI_8_BPW) &&
-+ ((pSpi->bits_per_word != IOH_SPI_16_BPW))) {
-+ IOH_LOG(KERN_ERR, "ioh_spi_setup Invalid bits per word\n");
-+ iRetVal = -EINVAL;
-+ }
-+
-+ /*Check baud rate setting */
-+ /*if baud rate of chip is greater than
-+ max we can support,return error */
-+ if ((pSpi->max_speed_hz) > IOH_SPI_MAX_BAUDRATE) {
-+ iRetVal = -EINVAL;
-+ IOH_LOG(KERN_ERR, "ioh_spi_setup Invalid Baud rate\n");
-+ }
-+
-+ IOH_DEBUG(KERN_ERR, "ioh_spi_setup MODE = %x\n",
-+ ((pSpi->mode) & (SPI_CPOL | SPI_CPHA)));
-+
-+ if (((pSpi->mode) & SPI_LSB_FIRST) != 0)
-+ IOH_DEBUG("ioh_spi_setup LSB_FIRST\n");
-+ else
-+ IOH_DEBUG("ioh_spi_setup MSB_FIRST\n");
-+
-+
-+ IOH_DEBUG("ioh_spi_setup Return=%d\n", iRetVal);
-+
-+ return iRetVal;
-+}
-+
-+/*! @ingroup SPI_InterfaceLayerAPI
-+
-+@fn ioh_spi_transfer(struct spi_device* pSpi,struct spi_message* pMsg)
-+
-+@remarks Validates the SPI message and pushes it onto queue of pending
-+ transfers
-+
-+ The main tasks performed by this method are:
-+ - If the list of transfers is empty return -EINVAL.
-+ - If the maximum baud rate is zero return -EINVAL.
-+ - If Tranmit buffer and Receive buffer both are invalid for
-+ any transfer return -EINVAL.
-+ - If the length of transfer is zero for any transfer return -EINVAL.
-+ - If maximum baud rate and bits per word are invalid return -EINVAL.
-+ - If status of SPI channel is STATUS_EXITING return -ESHUTDOWN.
-+ - If device is suspended return -EINVAL.
-+ - Add the SPI message to queue of pending SPI messages.
-+ - Schedule work queue handler to run.
-+
-+@note ioh_spi_transfer is registered by IOH SPI controller driver
-+ with SPI core as
-+ its transfer routine from the function @ref ioh_spi_probe.It
-+ is invoked by the kernel's SPI component when user invokes
-+ read,write or SPI_IOC_MESSAGE ioctl.
-+
-+@param pSpi [@ref IN] Contains reference to struct spi_device
-+
-+@param pMsg [@ref IN] Contains reference to struct spi_message
-+
-+@retval int
-+- @ref IOH_SPI_SUCCESS The function exists normally after adding the SPI message
-+ to queue of pending SPI messages and schedules work queue
-+ handler to run.
-+- -EINVAL Any of the paramters are found to be invalid or the system is
-+ suspended.
-+- -ESHUTDOWN When the status of the SPI channel is STATUS_EXITING
-+ The status STATUS_EXITING is set when ioh_spi_remove
-+ is invoked.
-+
-+@see
-+ - ioh_spi_probe
-+
-+<hr>
-+*/
-+int ioh_spi_transfer(struct spi_device *pSpi, struct spi_message *pMsg)
-+{
-+
-+ struct spi_transfer *pTransfer;
-+
-+ struct ioh_spi_data *pCtrlData = spi_master_get_devdata(pSpi->master);
-+ int iRetVal = IOH_SPI_SUCCESS;
-+
-+ do {
-+ /*validate spi message and baud rate */
-+ if (unlikely((list_empty(&pMsg->transfers) == 1) ||
-+ ((pSpi->max_speed_hz) == 0))) {
-+ if (list_empty(&pMsg->transfers) == 1) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_transfer list empty\n");
-+ }
-+
-+ if ((pSpi->max_speed_hz) == 0) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_tranfer maxspeed=%d\n",
-+ (pSpi->max_speed_hz));
-+ }
-+
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_transfer returning EINVAL\n");
-+
-+ iRetVal = -EINVAL;
-+ break;
-+ }
-+
-+ IOH_DEBUG("ioh_spi_transfer Transfer List not empty\n");
-+
-+ IOH_DEBUG("ioh_spi_transfer Transfer Speed is set\n");
-+
-+ /*validate Tx/Rx buffers and Transfer length */
-+ list_for_each_entry(pTransfer, &pMsg->transfers,
-+ transfer_list) {
-+ if ((((pTransfer->tx_buf) == NULL)
-+ && ((pTransfer->rx_buf) == NULL))
-+ || (pTransfer->len == 0)) {
-+ if (((pTransfer->tx_buf) == NULL)
-+ && ((pTransfer->rx_buf) == NULL)) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_transfer Tx and Rx\
-+ buffer NULL\n");
-+ }
-+
-+ if (pTransfer->len == 0) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_transfer Transfer\
-+ length invalid\n");
-+ }
-+
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_transfer returning EINVAL\n");
-+
-+ iRetVal = -EINVAL;
-+ break;
-+ }
-+
-+ IOH_DEBUG("ioh_spi_transfer Tx/Rx buffer valid\n");
-+
-+ IOH_DEBUG("ioh_spi_transfer Transfer length valid\n");
-+
-+ /*if baud rate hs been specified validate the same */
-+
-+ if (pTransfer->speed_hz) {
-+ if ((pTransfer->speed_hz) >
-+ IOH_SPI_MAX_BAUDRATE) {
-+ iRetVal = -EINVAL;
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_transfer Invalid\
-+ Baud rate\n");
-+ }
-+ }
-+
-+ /*if bits per word has been specified validate
-+ the same */
-+ if (pTransfer->bits_per_word) {
-+ if ((pTransfer->bits_per_word != IOH_SPI_8_BPW)
-+ && (pTransfer->bits_per_word !=
-+ IOH_SPI_16_BPW)) {
-+ iRetVal = -EINVAL;
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_transfer Invalid bits\
-+ per word\n");
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (iRetVal == -EINVAL)
-+ break;
-+
-+
-+ spin_lock(&pCtrlData->Lock);
-+
-+ /*We won't process any messages if we have been asked
-+ to terminate */
-+
-+ if (STATUS_EXITING == (pCtrlData->Status)) {
-+ spin_unlock(&pCtrlData->Lock);
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_transfer -pCtrlData->Status\
-+ = STATUS_EXITING"
-+ "returning ESHUTDOWN\n");
-+ iRetVal = -ESHUTDOWN;
-+ break;
-+ }
-+
-+ /*If suspended ,return -EINVAL */
-+ if (pCtrlData->pBoardData->bSuspended == true) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_transfer pCtrlData->\
-+ pBoardData->bSuspending"
-+ "= true returning EINVAL\n");
-+ spin_unlock(&pCtrlData->Lock);
-+ iRetVal = -EINVAL;
-+ break;
-+ }
-+
-+ /*set status of message */
-+ pMsg->actual_length = 0;
-+
-+ IOH_DEBUG
-+ ("ioh_spi_transfer - setting pMsg->status = -EINPROGRESS\n");
-+
-+ pMsg->status = -EINPROGRESS;
-+
-+ /*add message to queue */
-+ list_add_tail(&pMsg->queue, &pCtrlData->Queue);
-+
-+ IOH_DEBUG("ioh_spi_transfer - Invoked list_add_tail\n");
-+
-+ /*schedule work queue to run */
-+ queue_work(pCtrlData->pWorkQueue, &pCtrlData->Work);
-+
-+ IOH_DEBUG("ioh_spi_transfer - Invoked Queue Work\n");
-+
-+ spin_unlock(&pCtrlData->Lock);
-+
-+ } while (0);
-+
-+ IOH_DEBUG("ioh_spi_transfer RETURN=%d\n", iRetVal);
-+
-+ return iRetVal;
-+}
-+
-+/*! @ingroup SPI_InterfaceLayerAPI
-+
-+@fn ioh_spi_cleanup(struct spi_device* pSpi)
-+
-+@remarks Provides the Cleanup routine for IOH SPI driver
-+
-+@note This is a dummy function.
-+ It is not mandatory to have a cleanup function.
-+ If SPI master provides a cleanup function while they register
-+ with the SPI core, then SPI core invokes the cleanup function
-+ when SPI master calls spi_unregister_master function.This
-+ driver invokes spi_unregister_master from ioh_spi_remove
-+ function. Before invoking spi_unregister_master all the resources
-+ used is freed i.e. cleanup activities are handled in the
-+ @ref ioh_spi_remove function itself.This function is registered
-+ as the cleanup routine for this SPI controller driver from
-+ the @ref ioh_spi_probe function.
-+
-+@param pSpi [@ref IN] Contains reference to struct spi_device
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_probe
-+
-+<hr>
-+
-+*/
-+void ioh_spi_cleanup(struct spi_device *pSpi)
-+{
-+ IOH_DEBUG("spi_cleanup\n");
-+}
-+
-+/*! @ingroup SPI_UtilitiesAPI
-+
-+@fn ioh_spi_callback( struct ioh_spi_data* pCtrlData)
-+
-+@remarks Informs ioh_spi_process_messages that SPI data transfer is complete
-+
-+ The main tasks performed by this method are:
-+ - Set transfer status of the SPI channel to completed.
-+ - Inform this to @ref ioh_spi_process_messages.
-+
-+@note The reference to this callback function is saved in a global pointer
-+by the function @ref ioh_spi_entcb invoked from @ref ioh_spi_probe function.
-+This function is invoked by the interrupt handler ioh_spi_handler
-+after transfer complete interrupt is received indicating the end of
-+SPI data transfer.ioh_spi_callback wakes up ioh_spi_process_messages
-+which blocks till SPI data transfer is completed.
-+
-+@param pCtrldata [@ref IN] Contains reference to struct ioh_spi_data
-+
-+@retval None
-+
-+@see
-+ - ioh_spi_handler
-+ - ioh_spi_probe
-+
-+<hr>
-+*/
-+void ioh_spi_callback(struct ioh_spi_data *pCtrlData)
-+{
-+ IOH_DEBUG("ioh_ spi _callback waking up process\n");
-+ spin_lock(&pCtrlData->Lock);
-+ pCtrlData->bTransferComplete = true;
-+ wake_up(&pCtrlData->Wait);
-+ IOH_DEBUG("ioh_ spi _callback invoked wake_up\n");
-+ spin_unlock(&pCtrlData->Lock);
-+}
-diff -urN linux-2.6.33-rc3/drivers/spi/pch_spi_pci.c topcliff-2.6.33-rc3/drivers/spi/pch_spi_pci.c
---- linux-2.6.33-rc3/drivers/spi/pch_spi_pci.c 1970-01-01 09:00:00.000000000 +0900
-+++ topcliff-2.6.33-rc3/drivers/spi/pch_spi_pci.c 2010-03-17 20:05:19.000000000 +0900
-@@ -0,0 +1,811 @@
-+/**
-+ * @file ioh_spi_pci.c
-+ *
-+ * @brief This file contains the function definition for the PCI Layer APIs
-+ *
-+ * @version 0.94
-+ *
-+ * @par
-+ * -- Copyright Notice --
-+ *
-+ * @par
-+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
-+ * All rights reserved.
-+ *
-+ * @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.
-+ *
-+ * @par
-+ * -- End of Copyright Notice --
-+ */
-+
-+/*includes*/
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/device.h>
-+#include <linux/spi/spi.h>
-+#include <linux/workqueue.h>
-+#include <linux/delay.h>
-+#include <linux/ioport.h>
-+#include <linux/interrupt.h>
-+/*#include <asm/io.h> modify by checkpatch.pl*/
-+#include <linux/io.h>
-+#include "pch_spi.h"
-+#include "pch_spi_hal.h"
-+#include "pch_debug.h"
-+
-+/*! @ingroup SPI_PCILayer
-+
-+@def IOH_SPI_MAX_CS
-+
-+@brief Denotes the maximum chip select number possible.
-+
-+@note Currently this is just used to set the number of chip selects in
-+ spi_master structure in @ref ioh_spi_probe function.
-+
-+@see ioh_spi_probe
-+
-+<hr>
-+
-+*/
-+#define IOH_SPI_MAX_CS (0xFF)
-+
-+/*pci device ids*/
-+
-+/*! @ingroup SPI_PCILayer
-+
-+@brief Denotes the PCI device ID of the supported device.
-+
-+@see ioh_spi_pcidev_id
-+
-+<hr>
-+
-+*/
-+#ifndef FPGA
-+#define PCI_DEVICE_ID_IOH_SPI (0x8816) /*LSI*/
-+#else
-+#define PCI_DEVICE_ID_IOH_SPI (0x8005) /*FPGA*/
-+#endif
-+/*! @ingroup SPI_PCILayerAPI
-+
-+@fn ioh_spi_probe(struct pci_dev *pDev, const struct pci_device_id *id)
-+
-+@brief Implements the Probe functionality for IOH SPI driver
-+
-+@remarks Implements the Probe functionality for IOH SPI driver
-+
-+ The major tasks performed by this method are:
-+ - Register the callback function.
-+ - Enable the PCI device.
-+ - Allocate memory for SPI master.
-+ - Initialize members of SPI master structure.
-+ - Register the SPI master.
-+ - Invoke @ref ioh_spi_get_resources to acquire and initialize
-+ other resources needed by the driver.
-+
-+@note This function is invoked by the kernel when it detects
-+ a SPI device matching the vendor ID and device ID specified
-+ by this driver.
-+
-+@param pDev [@ref INOUT] contains reference to struct pci_dev
-+
-+@param id [@ref IN] contains reference to struct pci_device_id
-+
-+@retval int
-+- @ref IOH_SPI_SUCCESS The function exists successfully
-+- -ENOMEM spi_alloc_master API fails/kmalloc fails
-+- -EINVAL pci_enable_device fails/spi_register_master fails
-+ /ioh_spi_get_resources fails
-+- -EIO pci_enable_device fails
-+- -ENODEV spi_register_master API fails
-+- -ENOSYS ioh_spi_get_resources fails
-+- -ENOMEM ioh_spi_get_resources fails
-+
-+@see ioh_spi_pcidev
-+
-+<hr>
-+
-+*/
-+static int ioh_spi_probe(struct pci_dev *pDev, const struct pci_device_id *id)
-+{
-+
-+ struct spi_master *pMaster[IOH_SPI_MAX_DEV];
-+
-+ struct ioh_spi_board_data *pBoardData;
-+ int iRetVal, i, j;
-+
-+ IOH_DEBUG("ioh_spi_probe ENTRY\n");
-+ /*initialize the call back function */
-+ ioh_spi_entcb(ioh_spi_callback);
-+ IOH_DEBUG("ioh_spi_probe invoked ioh_spi_entcb\n");
-+
-+ do {
-+ /*allocate memory for private data */
-+ pBoardData =
-+ kmalloc(sizeof(struct ioh_spi_board_data), GFP_KERNEL);
-+
-+ if (pBoardData == NULL) {
-+ IOH_LOG(KERN_ERR,
-+ " ioh_spi_probe memory allocation for private\
-+ data failed\n");
-+ iRetVal = -ENOMEM;
-+ break;
-+ }
-+
-+ IOH_DEBUG
-+ (" ioh_spi_probe memory allocation for private data\
-+ success\n");
-+
-+ /*enable PCI device */
-+ iRetVal = pci_enable_device(pDev);
-+ if (iRetVal != 0) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_probe pci_enable_device FAILED\n");
-+
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_probe invoked kfree to free memory\
-+ allocated for pBoardData\n");
-+ kfree(pBoardData);
-+ break;
-+ }
-+
-+ IOH_DEBUG("ioh_spi_probe pci_enable_device returned=%d\n",
-+ iRetVal);
-+
-+ pBoardData->pDev = pDev;
-+
-+ /*alllocate memory for SPI master */
-+ i = 0;
-+
-+ do {
-+ pMaster[i] =
-+ spi_alloc_master(&pDev->dev,
-+ sizeof(struct ioh_spi_data));
-+
-+ if (pMaster[i] == NULL) {
-+ iRetVal = -ENOMEM;
-+
-+ if (i > 0) {
-+ j = 0;
-+
-+ do {
-+ spi_master_put(pMaster[j]);
-+ j++;
-+ IOH_DEBUG
-+ ("ioh_spi_probe invoked\
-+ spi_master_put\n");
-+ } while (j < i);
-+ }
-+
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_probe spi_alloc_master\
-+ failed\n");
-+
-+ break;
-+ }
-+
-+ i++;
-+ } while (i < IOH_SPI_MAX_DEV);
-+
-+ IOH_DEBUG("ioh_spi_probe spi_alloc_master returned non NULL\n");
-+
-+ if (iRetVal != 0) {
-+ kfree(pBoardData);
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_probe invoked kfree to free memory\
-+ allocated for pBoardData\n");
-+ pci_disable_device(pDev);
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_probe Invoked pci_disable_device\n");
-+ break;
-+ }
-+
-+ /*initialize members of SPI master */
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ pMaster[i]->bus_num = i;
-+ pMaster[i]->num_chipselect = IOH_SPI_MAX_CS;
-+ pMaster[i]->setup = ioh_spi_setup;
-+ IOH_DEBUG
-+ ("ioh_spi_probe setup member of SPI master\
-+ initialized\n");
-+ pMaster[i]->transfer = ioh_spi_transfer;
-+ IOH_DEBUG
-+ ("ioh_spi_probe transfer member of SPI master\
-+ initialized\n");
-+ pMaster[i]->cleanup = ioh_spi_cleanup;
-+ IOH_DEBUG
-+ ("ioh_spi_probe cleanup member of SPI master\
-+ initialized\n");
-+
-+ pBoardData->pCtrlData[i] =
-+ spi_master_get_devdata(pMaster[i]);
-+
-+ pBoardData->pCtrlData[i]->pMaster = pMaster[i];
-+ pBoardData->pCtrlData[i]->nCurrentChip = 255;
-+ pBoardData->pCtrlData[i]->pCurrentChip = NULL;
-+ pBoardData->pCtrlData[i]->bTransferComplete = false;
-+ pBoardData->pCtrlData[i]->pU16TxBuffer = NULL;
-+ pBoardData->pCtrlData[i]->pU16RxBuffer = NULL;
-+ pBoardData->pCtrlData[i]->TxIndex = 0;
-+ pBoardData->pCtrlData[i]->RxIndex = 0;
-+ pBoardData->pCtrlData[i]->bTransferActive = false;
-+ pBoardData->pCtrlData[i]->pBoardData = pBoardData;
-+
-+ /*Register the controller with the SPI core. */
-+ iRetVal = spi_register_master(pMaster[i]);
-+ if (iRetVal != 0) {
-+ spi_master_put(pMaster[i]);
-+ IOH_DEBUG
-+ ("ioh_spi_probe invoked spi_master_put\n");
-+ /*unregister master for any channel that has
-+ registered master */
-+
-+ if (i > 0) {
-+#if 0
-+ for (j = 0; j < i; j++) {
-+ spi_unregister_master(pMaster
-+ [j]);
-+ IOH_DEBUG
-+ ("ioh_spi_probe invoked\
-+ spi_unregister_master\n");
-+ }
-+#else
-+ spi_unregister_master(pMaster[0]);
-+ IOH_DEBUG
-+ ("ioh_spi_probe invoked\
-+ spi_unregister_master\n");
-+#endif
-+ }
-+
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_probe spi_register_\
-+ master FAILED\n");
-+
-+ break;
-+ }
-+
-+ IOH_DEBUG
-+ ("ioh_spi_probe spi_register_master\
-+ returned=%d\n",
-+ iRetVal);
-+ }
-+
-+ if (iRetVal != 0) {
-+ kfree(pBoardData);
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_probe invoked kfree to free memory\
-+ allocated for pBoardData\n");
-+ pci_disable_device(pDev);
-+ IOH_DEBUG("ioh_spi_probe invoked pci_disable\n");
-+ break;
-+ }
-+
-+ /*allocate resources for IOH SPI */
-+ iRetVal = ioh_spi_get_resources(pBoardData);
-+ if (iRetVal != IOH_SPI_SUCCESS) {
-+ /*
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ spi_unregister_master(pMaster[i]);
-+ IOH_DEBUG
-+ ("ioh_spi_probe invoked\
-+ spi_unregister_master\n");
-+ }
-+ */
-+ spi_unregister_master(pMaster[0]);
-+ IOH_DEBUG
-+ ("ioh_spi_probe invoked spi_unregister_master\n");
-+
-+
-+ kfree(pBoardData);
-+
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_probe invoked kfree to free memory\
-+ allocated for pBoardData\n");
-+ pci_disable_device(pDev);
-+ IOH_DEBUG("ioh_spi_probe invoked pci_disable\n");
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_probe get_resources FAILED\n");
-+ break;
-+ }
-+
-+ IOH_DEBUG("ioh_spi_probe ioh_spi_get_resources returned=%d\n",
-+ iRetVal);
-+
-+ /*save private data in dev */
-+ pci_set_drvdata(pDev, (void *)pBoardData);
-+ IOH_DEBUG("ioh_spi_probe invoked pci_set_drvdata\n");
-+
-+ /*set master mode */
-+
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ ioh_spi_set_master_mode(pMaster[i]);
-+ IOH_DEBUG
-+ ("ioh_spi_probe invoked ioh_spi_set_master_mode\n");
-+ }
-+
-+ iRetVal = IOH_SPI_SUCCESS;
-+
-+ } while (false);
-+
-+ IOH_DEBUG("ioh_spi_probe Return=%d\n", iRetVal);
-+
-+ return iRetVal;
-+}
-+
-+/*! @ingroup SPI_PCILayerAPI
-+
-+@fn ioh_spi_remove(struct pci_dev *pDev)
-+
-+@brief Implements the remove routine for IOH SPI driver
-+
-+@remarks Implements the remove routine for IOH SPI driver
-+
-+ The major tasks performed by this method are:
-+ - Invoke @ref ioh_spi_check_request_pending function to find
-+ out if there are any pending requests.
-+ - Free the allocated resources by invoking @ref ioh_spi_free_resources.
-+ - Unregister SPI master.
-+ - Disable PCI device.
-+
-+@note This function is invoked when the IOH SPI controller driver module
-+ is removed from the system using "rmmod" command OR when the SPI
-+ device is removed from the system.
-+
-+@param pDev [@ref INOUT] contains reference to struct pci_dev
-+
-+@retval None
-+
-+@see ioh_spi_pcidev
-+
-+<hr>
-+
-+*/
-+static void ioh_spi_remove(struct pci_dev *pDev)
-+{
-+ struct ioh_spi_board_data *pBoardData = pci_get_drvdata(pDev);
-+
-+ IOH_DEBUG("ioh_spi_remove ENTRY\n");
-+
-+ if (pBoardData != NULL) {
-+ IOH_DEBUG("ioh_spi_remove invoked pci_get_drvdata\n");
-+
-+ /*check for any pending messages */
-+
-+ if ((-EBUSY) == ioh_spi_check_request_pending(pBoardData)) {
-+ IOH_DEBUG
-+ ("ioh_spi_remove ioh_spi_check_request_pending\
-+ returned EBUSY\n");
-+ /*no need to take any particular action;proceed with
-+ remove even
-+ though queue is not empty */
-+ }
-+
-+ IOH_DEBUG
-+ ("ioh_spi_remove ioh_spi_check_request_pending invoked\n");
-+
-+ /*Free resources allocated for IOH SPI */
-+ ioh_spi_free_resources(pBoardData);
-+ IOH_DEBUG("ioh_spi_remove invoked ioh_spi_free_resources\n");
-+
-+ /*Unregister SPI master */
-+
-+#if 0
-+ int i;
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ spi_unregister_master(pBoardData->pCtrlData[i]->
-+ pMaster);
-+ IOH_DEBUG
-+ ("ioh_spi_remove invoked spi_unregister_master\n");
-+ }
-+#else
-+ spi_unregister_master(pBoardData->pCtrlData[0]->pMaster);
-+ IOH_DEBUG("ioh_spi_remove invoked spi_unregister_master\n");
-+
-+#endif
-+
-+ /*free memory for private data */
-+ kfree(pBoardData);
-+
-+ pci_set_drvdata(pDev, NULL);
-+
-+ IOH_DEBUG("ioh_spi_remove memory for private data freed\n");
-+
-+ /*disable PCI device */
-+ pci_disable_device(pDev);
-+
-+ IOH_DEBUG("ioh_spi_remove invoked pci_disable_device\n");
-+
-+ } else {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_remove pci_get_drvdata returned NULL\n");
-+ }
-+}
-+
-+/*! @ingroup SPI_PCILayerAPI
-+
-+@fn ioh_spi_suspend(struct pci_dev *pDev,pm_message_t state)
-+
-+@brief Implements the suspend routine for IOH SPI driver
-+
-+@remarks Implements the suspend routine for IOH SPI driver
-+
-+ The major tasks performed by this method are:
-+ - Wait till current message is processed.
-+ - Disable interrupts by invoking @ref ioh_spi_disable_interrupts.
-+ - Unregister the interrupt handler.
-+ - Save current state.
-+ - Disable PM notifications.
-+ - Disable PCI device.
-+ - Move the device to D3Hot power state.
-+
-+@note This function is invoked by the kernel when the system transitions
-+ to low power state.
-+
-+@param pDev [@ref INOUT] contains reference to struct pci_dev
-+
-+@param state [@ref IN] contains new PM state to which to transition to.
-+
-+@retval int
-+ - @ref IOH_SPI_SUCCESS The function returns successfully
-+ - -ENOMEM pci_save_state fails
-+
-+@see ioh_spi_pcidev
-+
-+<hr>
-+
-+*/
-+#ifdef CONFIG_PM
-+static int ioh_spi_suspend(struct pci_dev *pDev, pm_message_t state)
-+{
-+ int i;
-+ u8 count;
-+ s32 iRetVal = IOH_SPI_SUCCESS;
-+
-+ struct ioh_spi_board_data *pBoardData = pci_get_drvdata(pDev);
-+
-+ IOH_DEBUG("ioh_spi_suspend ENTRY\n");
-+
-+ if (pBoardData == NULL) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_suspend pci_get_drvdata returned NULL\n");
-+ iRetVal = -EFAULT;
-+ } else {
-+ IOH_DEBUG
-+ ("ioh_spi_suspend pci_get_drvdata invoked successfully\n");
-+ pBoardData->bSuspended = true;
-+ IOH_DEBUG
-+ ("ioh_spi_suspend pBoardData->bSuspending set to true\n");
-+
-+ /*check if the current message is processed:
-+ Only after thats done the transfer will be suspended */
-+
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ count = 255;
-+
-+ while ((--count) > 0) {
-+ if (pBoardData->pCtrlData[i]->
-+ bCurrent_msg_processing == false) {
-+ IOH_DEBUG
-+ ("ioh_spi_suspend pBoardData\
-+ ->pCtrlData->"
-+ "bCurrent_msg_processing\
-+ = false\n");
-+ break;
-+ } else {
-+ IOH_DEBUG
-+ ("ioh_spi_suspend pBoardData\
-+ ->pCtrlData->"
-+ "bCurrent_msg_processing = true\n");
-+ }
-+
-+ msleep(IOH_SPI_SLEEP_TIME);
-+ }
-+ }
-+
-+ /*Free IRQ */
-+ if (pBoardData->bIrqRegistered == true) {
-+ /*disable all interrupts */
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ ioh_spi_disable_interrupts(pBoardData->
-+ pCtrlData[i]->
-+ pMaster,
-+ IOH_SPI_ALL);
-+ ioh_spi_reset(pBoardData->pCtrlData[i]->
-+ pMaster);
-+ IOH_DEBUG
-+ ("ioh_spi_suspend ioh_spi_\
-+ disable_interrupts invoked"
-+ "successfully\n");
-+ }
-+
-+ free_irq(pBoardData->pDev->irq, (void *)pBoardData);
-+
-+ pBoardData->bIrqRegistered = false;
-+ IOH_DEBUG
-+ ("ioh_spi_suspend free_irq invoked successfully\n");
-+ IOH_DEBUG
-+ ("ioh_spi_suspend pCtrlData->bIrqRegistered\
-+ = false\n");
-+ }
-+
-+ /*save config space */
-+ iRetVal = pci_save_state(pDev);
-+
-+ if (iRetVal == 0) {
-+ IOH_DEBUG
-+ ("ioh_spi_suspend pci_save_state returned=%d\n",
-+ iRetVal);
-+ /*disable PM notifications */
-+ pci_enable_wake(pDev, PCI_D3hot, 0);
-+ IOH_DEBUG
-+ ("ioh_spi_suspend pci_enable_wake invoked\
-+ successfully\n");
-+ /*disable PCI device */
-+ pci_disable_device(pDev);
-+ IOH_DEBUG
-+ ("ioh_spi_suspend pci_disable_device invoked\
-+ successfully\n");
-+ /*move device to D3hot state */
-+ pci_set_power_state(pDev, PCI_D3hot);
-+ IOH_DEBUG
-+ ("ioh_spi_suspend pci_set_power_state invoked\
-+ successfully\n");
-+ } else {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_suspend pci_save_state failed\n");
-+ }
-+ }
-+
-+ IOH_DEBUG("ioh_spi_suspend return=%d\n", iRetVal);
-+
-+ return iRetVal;
-+}
-+
-+#endif
-+/*! @ingroup SPI_PCILayerAPI
-+
-+@fn ioh_spi_resume(struct pci_dev *pDev)
-+
-+@brief Implements the resume routine for IOH SPI driver
-+
-+@remarks Implements the resume routine for IOH SPI driver
-+
-+ The major tasks performed by this method are:
-+ - Move the device to D0 power state.
-+ - Restore the saved state.
-+ - Enable the PCI device.
-+ - Disable PM notifications.
-+ - Register interrupt handler.
-+ - Reset IOH SPI hardware.
-+ - Set IOH SPI hardware in master mode.
-+
-+@note This function is invoked by the kernel when the system is being
-+ resumed from suspend.
-+
-+@param pDev [@ref INOUT] contains reference to struct pci_dev
-+
-+@retval int
-+ - @ref IOH_SPI_SUCCESS The function returns successfully
-+ - -EINVAL request_irq fails
-+ - -ENOMEM request_irq fails
-+ - -ENOSYS request_irq fails
-+ - -EBUSY request_irq fails
-+ - -EIO pci_enable_device fails
-+
-+@see ioh_spi_pcidev
-+
-+<hr>
-+
-+*/
-+#ifdef CONFIG_PM
-+static int ioh_spi_resume(struct pci_dev *pDev)
-+{
-+ int i;
-+ s32 iRetVal = IOH_SPI_SUCCESS;
-+
-+ struct ioh_spi_board_data *pBoardData = pci_get_drvdata(pDev);
-+ IOH_DEBUG("ioh_spi_resume ENTRY\n");
-+
-+ if (pBoardData == NULL) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_resume pci_get_drvdata returned NULL\n");
-+ iRetVal = -EFAULT;
-+ } else {
-+ /*move device to DO power state */
-+ pci_set_power_state(pDev, PCI_D0);
-+ IOH_DEBUG
-+ ("ioh_spi_resume pci_set_power_state invoked successfully\n");
-+
-+ /*restore state */
-+ pci_restore_state(pDev);
-+ IOH_DEBUG
-+ ("ioh_spi_resume pci_restore_state invoked successfully\n");
-+ iRetVal = pci_enable_device(pDev);
-+ if (iRetVal < 0) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_resume pci_enable_device failed\n");
-+ } else {
-+ IOH_DEBUG
-+ ("ioh_spi_resume pci_enable_device returned=%d\n",
-+ iRetVal);
-+
-+ /*disable PM notifications */
-+ pci_enable_wake(pDev, PCI_D3hot, 0);
-+ IOH_DEBUG
-+ ("ioh_spi_resume pci_enable_wake invoked\
-+ successfully\n");
-+
-+ /*register IRQ handler */
-+
-+ if ((pBoardData->bIrqRegistered) != true) {
-+ /*register IRQ */
-+ iRetVal = request_irq(pBoardData->pDev->irq,
-+ ioh_spi_handler, IRQF_SHARED,
-+ DRIVER_NAME,
-+ pBoardData);
-+ if (iRetVal < 0) {
-+ IOH_LOG(KERN_ERR,
-+ "ioh_spi_resume\
-+ request_irq failed\n");
-+ } else {
-+ IOH_DEBUG
-+ ("ioh_spi_resume request_irq\
-+ returned=%d\n",
-+ iRetVal);
-+ pBoardData->bIrqRegistered = true;
-+
-+ /*reset IOH SPI h/w */
-+
-+ for (i = 0; i < IOH_SPI_MAX_DEV; i++) {
-+ ioh_spi_reset(pBoardData->
-+ pCtrlData[i]->
-+ pMaster);
-+ IOH_DEBUG
-+ ("ioh_spi_resume\
-+ ioh_spi_reset invoked "
-+ "successfully \n");
-+ ioh_spi_set_master_mode
-+ (pBoardData->pCtrlData[i]->
-+ pMaster);
-+ IOH_DEBUG
-+ ("ioh_spi_resume\
-+ ioh_spi_set_master_mode invoked"
-+ "successfully \n");
-+ }
-+
-+ /*set suspend status to false */
-+ pBoardData->bSuspended = false;
-+
-+ IOH_DEBUG
-+ ("ioh_spi_resume set pBoardData->\
-+ bSuspending = false\n");
-+ }
-+ }
-+ }
-+ }
-+
-+ IOH_DEBUG("ioh_spi_resume returning=%d\n", iRetVal);
-+
-+ return iRetVal;
-+}
-+
-+#endif
-+/*! @ingroup SPI_PCILayerFacilitators
-+
-+@struct ioh_spi_pcidev_id
-+
-+@brief Store information of supported PCI devices
-+
-+@see ioh_spi_pcidev
-+
-+<hr>
-+
-+*/
-+
-+static struct pci_device_id ioh_spi_pcidev_id[] = {
-+ /*LSI*/ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_IOH_SPI)},
-+ {0,}
-+
-+};
-+
-+/*! @ingroup SPI_PCILayerFacilitators
-+
-+@struct ioh_spi_pcidev
-+
-+@brief Store the references of PCI driver interfaces to kernel
-+
-+@note This structure is registerd with the kernel via the call
-+ pci_register_driver from @ref ioh_spi_init
-+
-+@see
-+ - ioh_spi_init
-+ - ioh_spi_exit
-+
-+<hr>
-+
-+*/
-+
-+static struct pci_driver ioh_spi_pcidev = {
-+ .name = "ioh_spi",
-+ .id_table = ioh_spi_pcidev_id,
-+ .probe = ioh_spi_probe,
-+ .remove = ioh_spi_remove,
-+#ifdef CONFIG_PM
-+ .suspend = ioh_spi_suspend,
-+ .resume = ioh_spi_resume,
-+#endif
-+
-+};
-+
-+/*! @ingroup SPI_InterfaceLayerAPI
-+
-+@fn ioh_spi_init(void)
-+
-+@brief Entry point function for this module.
-+
-+@remarks Init function for IOH SPI driver module
-+
-+@param None
-+
-+@retval int
-+ - 0 Function exits successfully
-+ - -EEXIST pci_register_driver fails
-+ - -EINVAL pci_register_driver fails
-+ - -ENOMEM pci_register_driver fails
-+
-+<hr>
-+
-+*/
-+static int __init ioh_spi_init(void)
-+{
-+ s32 iRetVal;
-+
-+ iRetVal = pci_register_driver(&ioh_spi_pcidev);
-+ if (iRetVal == 0) {
-+ IOH_DEBUG
-+ ("ioh_spi_init pci_register_driver invoked successfully\n");
-+ } else {
-+ IOH_LOG(KERN_ERR, "ioh_spi_init pci_register_driver failed\n");
-+ }
-+
-+ IOH_DEBUG("ioh_spi_init returning=%d\n", iRetVal);
-+
-+ return iRetVal;
-+}
-+
-+/*! @ingroup SPI_InterfaceLayerAPI
-+
-+@fn ioh_spi_exit(void)
-+
-+@brief Exit point function for this module.
-+
-+@remarks Function invoked when module is removed
-+
-+@param None
-+
-+@retval None
-+
-+<hr>
-+
-+*/
-+static void __exit ioh_spi_exit(void)
-+{
-+ IOH_DEBUG("ioh_spi_exit Invoking pci_unregister_driver\n");
-+ pci_unregister_driver(&ioh_spi_pcidev);
-+}
-+
-+MODULE_DESCRIPTION("IOH SPI PCI Driver");
-+MODULE_LICENSE("GPL");
-+module_init(ioh_spi_init);
-+module_exit(ioh_spi_exit);
-diff -urN linux-2.6.33-rc3/drivers/spi/pch_spi_platform_devices.c topcliff-2.6.33-rc3/drivers/spi/pch_spi_platform_devices.c
---- linux-2.6.33-rc3/drivers/spi/pch_spi_platform_devices.c 1970-01-01 09:00:00.000000000 +0900
-+++ topcliff-2.6.33-rc3/drivers/spi/pch_spi_platform_devices.c 2010-03-06 07:44:02.000000000 +0900
-@@ -0,0 +1,50 @@
-+#include <linux/module.h>
-+#include <linux/spi/spidev.h>
-+#include <linux/device.h>
-+#include <linux/spi/spi.h>
-+
-+static struct spi_board_info ioh_spi_slaves[] = {
-+ {
-+ .modalias = "spidev", /* Name of spi_driver for this device*/
-+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ*/
-+ .bus_num = 0, /* Framework bus number*/
-+ .chip_select = 0, /* Framework chip select.*/
-+ .platform_data = NULL,
-+ .mode = SPI_MODE_0,
-+ },
-+#if (CONFIG_PCH_SPI_PLATFORM_DEVICE_COUNT - 1)
-+ {
-+ .modalias = "spidev", /* Name of spi_driver for this device*/
-+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ*/
-+ .bus_num = 1, /* Framework bus number*/
-+ .chip_select = 0, /* Framework chip select.*/
-+ .platform_data = NULL,
-+ .mode = SPI_MODE_0,
-+ },
-+#endif
-+};
-+
-+static __init int Load(void)
-+{
-+ int iRetVal = -1;
-+
-+ printk(KERN_INFO "Registering IOH SPI devices... \n");
-+
-+ if (!spi_register_board_info
-+ (ioh_spi_slaves, ARRAY_SIZE(ioh_spi_slaves)))
-+ iRetVal = 0;
-+ else
-+ printk(KERN_ERR "Registering IOH SPI devices failed\n");
-+
-+ return iRetVal;
-+}
-+
-+/*
-+ * static __exit void Unload()
-+ * {
-+ *
-+ * }
-+ * */
-+
-+module_init(Load);
-+MODULE_LICENSE("GPL");