summaryrefslogtreecommitdiff
path: root/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-ieee1588.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-ieee1588.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-ieee1588.patch7945
1 files changed, 7945 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-ieee1588.patch b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-ieee1588.patch
new file mode 100644
index 000000000..ac1bea905
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-ieee1588.patch
@@ -0,0 +1,7945 @@
+
+
+From: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
+Subject: OKI Semiconductor PCH IEEE1588 driver
+
+This driver implements IEEE1588 controls for PCH.
+
+Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
+Acked-by: Wang Qi <qi.wang@intel.com>
+
+---
+ drivers/char/Kconfig | 7 ++
+ drivers/char/Makefile | 2
+ drivers/char/pch_ieee1588/Makefile | 10
+ drivers/char/pch_ieee1588/pch_1588_hal.c | 4040
+ drivers/char/pch_ieee1588/pch_1588_hal.h | 885
+ drivers/char/pch_ieee1588/pch_1588_main.c | 1192
+ drivers/char/pch_ieee1588/pch_1588_main.h | 702
+ drivers/char/pch_ieee1588/pch_1588_pci.c | 700
+ drivers/char/pch_ieee1588/pch_1588_pci.h | 122
+ drivers/char/pch_ieee1588/pch_common.h | 146
+ drivers/char/pch_ieee1588/pch_debug.h | 60
++++++++++++++++++++++++++++++++ 11 files changed, zz insertions(+)
+diff -urN linux-2.6.33-rc3/drivers/char/Kconfig topcliff-2.6.33-rc3/drivers/char/Kconfig
+--- linux-2.6.33-rc3/drivers/char/Kconfig 2010-01-06 09:02:46.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/Kconfig 2010-03-09 10:14:52.000000000 +0900
+@@ -4,6 +4,13 @@
+
+ menu "Character devices"
+
++config PCH_IEEE1588
++ tristate "PCH IEEE1588"
++ depends on PCI
++ help
++ If you say yes to this option, support will be included for the
++ PCH IEEE1588 Host controller.
++
+ config VT
+ bool "Virtual terminal" if EMBEDDED
+ depends on !S390
+diff -urN linux-2.6.33-rc3/drivers/char/Makefile topcliff-2.6.33-rc3/drivers/char/Makefile
+--- linux-2.6.33-rc3/drivers/char/Makefile 2010-01-06 09:02:46.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/Makefile 2010-03-05 22:57:39.000000000 +0900
+@@ -111,6 +111,8 @@
+ obj-$(CONFIG_JS_RTC) += js-rtc.o
+ js-rtc-y = rtc.o
+
++obj-$(CONFIG_PCH_IEEE1588) += pch_ieee1588/
++
+ # Files generated that shall be removed upon make clean
+ clean-files := consolemap_deftbl.c defkeymap.c
+
+diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/Makefile topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/Makefile
+--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/Makefile 1970-01-01 09:00:00.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/Makefile 2010-03-10 04:52:54.000000000 +0900
+@@ -0,0 +1,10 @@
++ifeq ($(CONFIG_IEEE1588_DEBUG_CORE),y)
++EXTRA_CFLAGS += -DDEBUG
++endif
++
++obj-$(CONFIG_PCH_IEEE1588) += pch_ieee1588.o
++
++#for A0_A1_SAMPLE LSI board
++EXTRA_CFLAGS+=-DIOH_IEEE1588_A0_A1_SAMPLE_BUG
++
++pch_ieee1588-objs := pch_1588_main.o pch_1588_pci.o pch_1588_hal.o
+diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.c topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.c
+--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.c 1970-01-01 09:00:00.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.c 2010-03-09 10:34:22.000000000 +0900
+@@ -0,0 +1,4040 @@
++ /*!
++ * @file ioh_1588_hal.c
++ * @brief
++ * This file has the definitions for HALLAyer APIs.
++ * @version 0.92
++ * @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:
++ * modified to support Intel IOH GE IEEE 1588 hardware
++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
++ * All rights reserved.
++ * derived from
++ * IEEE 1588 Time Synchronization Driver for Intel EP80579
++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ * All rights reserved.
++ *
++ */
++
++#include <linux/io.h>
++#include "pch_common.h"
++#include "pch_debug.h"
++#include <linux/module.h>
++#include "pch_1588_hal.h"
++
++/*
++ * HAL API definitions for the IEEE 1588 module
++ */
++
++/*! @ingroup IEEE1588
++ * @def INLINE
++ * @brief The macro used instead of the keyword __inline.
++*/
++#define INLINE inline
++
++/*Register read/write macros*/
++#define IOH_REG_32_READ(regAddr, varRef) (*(varRef) = IOH_READ32(regAddr))
++#define IOH_REG_32_WRITE(regAddr, varValue) IOH_WRITE32(varValue, regAddr)
++#define IOH_BIT_SET_CHECK(regAddr, bitMask) \
++ ((IOH_READ32(regAddr) & (bitMask)) == (bitMask))
++
++#ifdef IOH_IEEE1588_A1_SAMPLE_BUG
++/*global variable to store tick rate*/
++static unsigned long gTickRateApp;
++#endif
++
++/* function prototypes */
++/* TS_Control register access routines */
++static INLINE void ioh_1588_pps_imask_set(void);
++static INLINE void ioh_1588_amms_imask_set(void);
++static INLINE void ioh_1588_asms_imask_set(void);
++static INLINE void ioh_1588_ttm_imask_set(void);
++static INLINE void ioh_1588_pps_imask_clear(void);
++static INLINE void ioh_1588_amms_imask_clear(void);
++static INLINE void ioh_1588_asms_imask_clear(void);
++static INLINE void ioh_1588_ttm_imask_clear(void);
++static INLINE unsigned long ioh_1588_pps_imask_get(void);
++static INLINE unsigned long ioh_1588_amms_imask_get(void);
++static INLINE unsigned long ioh_1588_asms_imask_get(void);
++static INLINE unsigned long ioh_1588_ttm_imask_get(void);
++static INLINE void ioh_1588_block_reset(void);
++
++/* TS_Event register access routines */
++static INLINE unsigned long ioh_1588_pps_evt_get(void);
++static INLINE unsigned long ioh_1588_amms_evt_get(void);
++static INLINE unsigned long ioh_1588_asms_evt_get(void);
++static INLINE unsigned long ioh_1588_ttm_evt_get(void);
++static INLINE void ioh_1588_pps_evt_clear(void);
++static INLINE void ioh_1588_amms_evt_clear(void);
++static INLINE void ioh_1588_asms_evt_clear(void);
++static INLINE void ioh_1588_ttm_evt_clear(void);
++
++/* TS_Addend register access routines - Frequency Scaling Value */
++static INLINE void ioh_1588_addend_set(unsigned long fsv);
++static INLINE void ioh_1588_addend_get(unsigned long *fsv);
++
++/* TS_PPS_Compare register access routines */
++static INLINE void ioh_1588_pps_set(unsigned long fsv);
++static INLINE void ioh_1588_pps_get(unsigned long *fsv);
++/* TS_SYSTimeLo, Hi registers access routines */
++static INLINE void ioh_1588_sys_snap_set(unsigned long sys_time_low,
++ unsigned long sys_time_high);
++static INLINE void ioh_1588_sys_snap_get(unsigned long *sys_time_low,
++ unsigned long *sys_time_high);
++/* TS_TrgtTimeLo, Hi registers access routines */
++static INLINE void ioh_1588_tgt_snap_set(unsigned long tgt_time_low,
++ unsigned long tgt_time_high);
++static INLINE void ioh_1588_tgt_snap_get(unsigned long *tgt_time_low,
++ unsigned long *tgt_time_high);
++/* TS_ASMSLo, Hi registers access routines */
++static INLINE void ioh_1588_aux_slave_snap_get(unsigned long *asms_low,
++ unsigned long *asms_high);
++/* TS_AMMSLo, Hi registers access routines */
++static INLINE void ioh_1588_aux_master_snap_get(unsigned long *amms_low,
++ unsigned long *amms_high);
++
++/* TS_Ch_Control register access routines */
++static INLINE void ioh_1588_master_mode_set(unsigned long master_mode);
++static INLINE unsigned long ioh_1588_master_mode_get(void);
++static INLINE void ioh_1588_timestamp_all_set(unsigned long allMsg);
++static INLINE unsigned long ioh_1588_timestamp_all_get(void);
++static INLINE void ioh_1588_op_mode_set(unsigned long mode);
++static INLINE unsigned long ioh_1588_op_mode_get(void);
++static INLINE void ioh_1588_version_set(unsigned long versionVal);
++static INLINE unsigned long ioh_1588_version_get(void);
++
++/* TS_Ch_Event register access routines */
++static INLINE unsigned long ioh_1588_rx_snap_evt(void);
++static INLINE unsigned long ioh_1588_tx_snap_evt(void);
++static INLINE void ioh_1588_rx_snap_evt_clear(void);
++static INLINE void ioh_1588_tx_snap_evt_clear(void);
++/* TS_TxSnapLo, Hi registers access routines */
++static INLINE void ioh_1588_tx_snap_get(unsigned long *txs_low,
++ unsigned long *txs_high);
++/* TS_RxSnapLo, Hi registers access routines */
++static INLINE void ioh_1588_rx_snap_get(unsigned long *rxs_low,
++ unsigned long *rxs_high);
++/* TS_srcUUIDLo, Hi registers access routines */
++static INLINE void ioh_1588_uuid_seqid_get(unsigned long *uuid_low,
++ unsigned long *uuid_high,
++ unsigned int *seq_id);
++
++static INLINE unsigned long ioh_1588_can_snap_valid(void);
++static INLINE unsigned long ioh_1588_can_snap_ovr(void);
++static INLINE void ioh_1588_can_snap_valid_clear(void);
++static INLINE void ioh_1588_can_snap_ovr_clear(void);
++static INLINE void ioh_1588_can_snap_get(unsigned long *rxs_low,
++ unsigned long *rxs_high);
++
++static INLINE void ioh_1588_eth_enable_set(void);
++static INLINE void ioh_1588_eth_enable_clear(void);
++static INLINE unsigned long ioh_1588_eth_enable_get(void);
++static INLINE void ioh_1588_can_enable_set(void);
++static INLINE void ioh_1588_can_enable_clear(void);
++static INLINE unsigned long ioh_1588_can_enable_get(void);
++static INLINE void ioh_1588_station_set(unsigned long station,
++ unsigned long value);
++static INLINE void ioh_1588_station_get(unsigned long station,
++ unsigned long *value);
++
++/* Masks to extract High and Low SHORTs from unsigned long values */
++#define IOH_1588_MSB_SHORT_MASK (0xFFFF0000)
++#define IOH_1588_LSB_SHORT_MASK (0x0000FFFF)
++
++/* Location of SeqID in the register */
++#define IOH_1588_SID_LOC (16)
++
++/* Variable declarations */
++
++/**
++ * Client registered callback routines for
++ * a) the target time reached or exceeded interrupt notification
++ * b) the auxiliary time stamps availability interrupt notification
++ * c) the pulse per second match interrupt notification
++ */
++static ioh1588TargetTimeCallback ioh_tt_cbptr =
++ (ioh1588TargetTimeCallback) NULL;
++static ioh1588AuxTimeCallback ioh_am_cbptr = (ioh1588AuxTimeCallback) NULL;
++static ioh1588AuxTimeCallback ioh_as_cbptr = (ioh1588AuxTimeCallback) NULL;
++static ioh1588PulsePerSecondCallback ioh_pps_cbptr =
++ (ioh1588PulsePerSecondCallback) NULL;
++
++/* The transmit and receive timestamp statistics */
++static struct ioh1588Stats ioh_1588_stats = { 0, 0 };
++
++/* To save the state of all registers of the module */
++static struct ioh_1588_regs_set ioh_1588_regs;
++
++/* IO mapped virtual address for the 1588 registers */
++static unsigned long ioh_1588_base;
++
++/* local functions definitions. */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_pps_imask_set(void)
++ * @brief Enable PPS Interrupt
++ * @param None
++ * @retval None
++*/
++
++static INLINE void ioh_1588_pps_imask_set(void)
++{
++ /* SET the ppsm bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_PPSM_MASK);
++}
++
++/** @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_amms_imask_set(void)
++ * @brief Enable Auxiliary Master Mode Snapshot Interrupt
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_amms_imask_set(void)
++{
++ /* SET the amms bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_AMMS_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_asms_imask_set(void)
++ * @brief Enable Auxiliary Slave Mode Snapshot Interrupt
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_asms_imask_set(void)
++{
++ /* SET the asms bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_ASMS_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_ttm_imask_set(void)
++ * @brief Enable Target Time Interrupt
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_ttm_imask_set(void)
++{
++ /* SET the ttm bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_TTM_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_pps_imask_get(void)
++ * @brief Get PPS Interrupt Mask value
++ * @param None
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_pps_imask_get(void)
++{
++ /* Is the ppsm bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_PPSM_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_amms_imask_get(void)
++ * @brief Get Auxiliary Master Mode Snapshot Interrupt Mask value
++ * @param None
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_amms_imask_get(void)
++{
++ /* Is the amms bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_AMMS_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ @fn static INLINE unsigned long ioh_1588_asms_imask_get(void)
++ @brief Get Auxiliary Slave Mode Snapshot Interrupt Mask value
++ @param None
++ @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_asms_imask_get(void)
++{
++ /* Is the asms bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_ASMS_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_ttm_imask_get(void)
++ * @brief Get Target Time Interrupt Mask value
++ * @param None.
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_ttm_imask_get(void)
++{
++ /* Is the ttm bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_TTM_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ @fn static INLINE void ioh_1588_pps_imask_clear(void)
++ @brief Disable PPS Interrupt
++ @param None
++ @retval None
++*/
++static INLINE void ioh_1588_pps_imask_clear(void)
++{
++ /* CLEAR the ppsm bit */
++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_PPSM_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_amms_imask_clear(void)
++ * @brief Disable Auxiliary Master Mode Snapshot Interrupt.
++ * @param None.
++ * @retval None
++*/
++static INLINE void ioh_1588_amms_imask_clear(void)
++{
++ /* CLEAR the amms bit */
++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_AMMS_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_asms_imask_clear(void)
++ * @brief Disable Auxiliary Slave Mode Snapshot Interrupt
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_asms_imask_clear(void)
++{
++ /* CLEAR the asms bit */
++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_ASMS_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_ttm_imask_clear(void)
++ * @brief Disable Target Time Interrupt
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_ttm_imask_clear(void)
++{
++ /* CLEAR the ttm bit */
++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_TTM_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_block_reset(void)
++ * @brief Reset Hardware Assist block
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_block_reset(void)
++{
++ /* SET the rst bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_RESET);
++ /* CLEAR the rst bit */
++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET,
++ IOH_1588_TSC_RESET);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_pps_evt_get(void)
++ * @brief Poll for PPS event
++ * @param None
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_pps_evt_get(void)
++{
++ /* Check for PPS event */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSE_OFFSET,
++ IOH_1588_TSE_PPS);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_amms_evt_get(void)
++ * @brief Poll for Auxiliary Master Mode Snapshot Captured event
++ * @param None
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_amms_evt_get(void)
++{
++ /* Check for AMMS event */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSE_OFFSET,
++ IOH_1588_TSE_SNM);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_asms_evt_get(void)
++ * @brief Poll for Auxiliary Slave Mode Snapshot Captured event
++ * @param None
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_asms_evt_get(void)
++{
++ /* Check ASMS event */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSE_OFFSET,
++ IOH_1588_TSE_SNS);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_ttm_evt_get(void)
++ * @brief Poll for Target Time Reached event
++ * @param None
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_ttm_evt_get(void)
++{
++ /* Check target time pending event */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSE_OFFSET,
++ IOH_1588_TSE_TTIPEND);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_pps_evt_clear(void)
++ * @brief Clear PPS event
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_pps_evt_clear(void)
++{
++ /* clear the pps bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSE_OFFSET, IOH_1588_TSE_PPS);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_amms_evt_clear(void)
++ * @brief Clear Auxiliary Master Mode Snapshot Captured event
++ * @param None.
++ * @retval None.
++*/
++static INLINE void ioh_1588_amms_evt_clear(void)
++{
++ /* clear the snm bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSE_OFFSET, IOH_1588_TSE_SNM);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_asms_evt_clear(void)
++ * @brief Clear Auxiliary Slave Mode Snapshot Captured event
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_asms_evt_clear(void)
++{
++ /* clear the sns bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSE_OFFSET, IOH_1588_TSE_SNS);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_ttm_evt_clear(void)
++ * @brief Clear Target Time Reached event
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_ttm_evt_clear(void)
++{
++ /* CLEAR the ttipend bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSE_OFFSET,
++ IOH_1588_TSE_TTIPEND);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_sys_snap_set(
++ * unsigned long sys_time_low, unsigned long sys_time_high)
++ * @brief Set System Time value
++ * @param sys_time_low [IN] The system time low.
++ * @param sys_time_high {In} The system time high.
++ * @retval None
++*/
++static INLINE void
++ioh_1588_sys_snap_set(unsigned long sys_time_low, unsigned long sys_time_high)
++{
++ /* Update the System Time Low Register contents */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_STL_OFFSET, sys_time_low);
++
++ /* Update the System Time High Register contents */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_STH_OFFSET, sys_time_high);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE voidioh_1588_sys_snap_get(
++ * unsigned long *sys_time_low, unsigned long *sys_time_high)
++ * @brief Get System Time Low value
++ * @param sys_time_low [OUT] The system time low.
++ * @param sys_time_high [OUT] The system time high.
++ * @retval None
++*/
++static INLINE void
++ioh_1588_sys_snap_get(unsigned long *sys_time_low, unsigned long *sys_time_high)
++{
++ /* Get the System Time Low Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_STL_OFFSET, sys_time_low);
++
++ /* Get the System Time High Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_STH_OFFSET, sys_time_high);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_tgt_snap_set (
++ * unsigned long tgt_time_low, unsigned long tgt_time_high)
++ * @brief Set Target Time value
++ * @param tgt_time_low [IN] The target time low.
++ * @param tgt_time_high [IN] The target time high.
++ * @retval None.
++*/
++static INLINE void
++ioh_1588_tgt_snap_set(unsigned long tgt_time_low, unsigned long tgt_time_high)
++{
++ /* Update the Target Time Low Register contents */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_TTL_OFFSET, tgt_time_low);
++
++ /* Update the Target Time High Register contents */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_TTH_OFFSET, tgt_time_high);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_tgt_snap_get(
++ * unsigned long *tgt_time_low, unsigned long *tgt_time_high)
++ * @brief Get Target Time value
++ * @param tgt_time_low [OUT] The target time low.
++ * @param tgt_time_high [IN] The target time high.
++ * @retval None
++*/
++static INLINE void
++ioh_1588_tgt_snap_get(unsigned long *tgt_time_low, unsigned long *tgt_time_high)
++{
++ /* Get the Target Time Low Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_TTL_OFFSET, tgt_time_low);
++
++ /* Get the Target Time High Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_TTH_OFFSET, tgt_time_high);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_addend_set(unsigned long fsv)
++ * @brief Set Frequency Scaling Value
++ * @param fsv [IN] Frequency
++ * @retval None
++*/
++static INLINE void ioh_1588_addend_set(unsigned long fsv)
++{
++ /* Update the Addend Register contents */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_ADD_OFFSET, fsv);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_addend_get(unsigned long *fsv)
++ * @brief Get Frequency Scaling Value
++ * @param fsv [OUT] The frequency.
++ * @retval None
++*/
++static INLINE void ioh_1588_addend_get(unsigned long *fsv)
++{
++ /* Get the Addend Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_ADD_OFFSET, fsv);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_pps_set(unsigned long pps)
++ * @brief Set Pulse Per Second Value
++ * @param pps [IN] The pulse per second value.
++ * @retval None.
++*/
++static INLINE void ioh_1588_pps_set(unsigned long pps)
++{
++ /* Update the PPS Compare Register contents */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_PPS_OFFSET, pps);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_pps_get(unsigned long *pps)
++ * @brief Get Pulse Per Second Value
++ * @param pps [OUT] The pulse per second value.
++ * @retval None.
++*/
++static INLINE void ioh_1588_pps_get(unsigned long *pps)
++{
++ /* Get the PPS Compare Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_PPS_OFFSET, pps);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_aux_master_snap_get(
++ * unsigned long *amms_low, unsigned long *amms_high)
++ * @brief Get AMMS value
++ * @param amms_low [OUT] AMMS low value.
++ * @param amms_high [OUT] AMMS high value.
++ * @retval None.
++*/
++static INLINE void
++ioh_1588_aux_master_snap_get(unsigned long *amms_low, unsigned long *amms_high)
++{
++ /* Get the Auxiliary Master Mode Snapshot Low Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_AMSL_OFFSET, amms_low);
++
++ /* Get the Auxiliary Master Mode Snapshot High Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_AMSH_OFFSET, amms_high);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_aux_slave_snap_get(
++ * unsigned long *asms_low, unsigned long *asms_high)
++ * @brief Get ASMS value
++ * @param asms_low [OUT] The ASMS low value.
++ * @param asms_high [OUT] The ASMS high value.
++ * @retval None
++*/
++static INLINE void
++ioh_1588_aux_slave_snap_get(unsigned long *asms_low, unsigned long *asms_high)
++{
++ /* Get the Auxiliary Slave Mode Snapshot Low Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_ASSL_OFFSET, asms_low);
++
++ /* Get the Auxiliary Slave Mode Snapshot High Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_ASSH_OFFSET, asms_high);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_master_mode_set(
++ * unsigned long master_mode)
++ * @brief Set the channel mode to 1588 Master/Slave
++ * @param master_mode [IN] The channel mode.
++ * @retval None
++*/
++static INLINE void ioh_1588_master_mode_set(unsigned long master_mode)
++{
++ /* SET or CLEAR the Master Mode */
++ if (TRUE == master_mode) {
++ IOH_DEBUG("ioh_1588_master_mode_set: setting master mode\n");
++ /* SET the mm bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET,
++ IOH_1588_CC_MM);
++ } else {
++ IOH_DEBUG("ioh_1588_master_mode_set: clearing master mode\n");
++ /* CLEAR the mm bit */
++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET,
++ IOH_1588_CC_MM);
++ }
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_master_mode_get (void)
++ * @brief Check for 1588 master mode of channel
++ * @param None.
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_master_mode_get(void)
++{
++ /* Is the mm bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CC_OFFSET,
++ IOH_1588_CC_MM);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_timestamp_all_set(
++ * unsigned long allMsg)
++ * @brief Set Timestamp all or only PTP messages flag
++ * @param allMsg [IN] All/PTP messages.
++ * @retval None
++*/
++static INLINE void ioh_1588_timestamp_all_set(unsigned long allMsg)
++{
++ /* SET or CLEAR the All Message Timestamping */
++ if (TRUE == allMsg) {
++ IOH_DEBUG
++ ("ioh_1588_timestamp_all_set: time stamp all messages\n");
++ /* SET the ta bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET,
++ IOH_1588_CC_TA);
++ } else { /* else of if (TRUE == allMsg) */
++
++ IOH_DEBUG
++ ("ioh_1588_timestamp_all_set: time stamp PTP messages \
++ only\n");
++ /* CLEAR the ta bit */
++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET,
++ IOH_1588_CC_TA);
++ }
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_timestamp_all_get(void)
++ * @brief Check for Timestamp all OR only PTP messages flag
++ * @param None.
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_timestamp_all_get(void)
++{
++ /* Is the ta bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CC_OFFSET,
++ IOH_1588_CC_TA);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_version_set(
++ * unsigned long versionVal)
++ * @brief Set the 1588 version number
++ * @param versionVal [IN] The version value.
++ * @retval None.
++*/
++static INLINE void ioh_1588_version_set(unsigned long versionVal)
++{
++ if (TRUE == versionVal) {
++ IOH_DEBUG
++ ("ioh_1588_version_set supports IEEE1588 v1 and \
++ IEEE1588-2008\n");
++ /* SET the version bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET,
++ IOH_1588_CC_VERSION);
++ } else {
++ IOH_DEBUG("ioh_1588_version_set supports IEEE1588 v1 only\n");
++ /* CLEAR the version bit */
++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET,
++ IOH_1588_CC_VERSION);
++ }
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_version_get (void)
++ * @brief Get the 1588 version number
++ * @param None.
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_version_get(void)
++{
++ /* Is the version bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CC_OFFSET,
++ IOH_1588_CC_VERSION);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_can_snap_valid (void)
++ * @brief CAN Timestamp available
++ * @param None
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_can_snap_valid(void)
++{
++ /* Is the valid bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CCE_OFFSET,
++ IOH_1588_CE_VAL);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_can_snap_ovr(void)
++ * @brief CAN Timestamp overrun
++ * @param None
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_can_snap_ovr(void)
++{
++ /* Is the ovr bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CCE_OFFSET,
++ IOH_1588_CE_OVR);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_can_snap_valid_clear(void)
++ * @brief Clear CAN Timestamp valid flag
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_can_snap_valid_clear(void)
++{
++ /* CLEAR the valid bit by writing '1' onto it */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_CCE_OFFSET, IOH_1588_CE_VAL);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_can_snap_ovr_clear(void)
++ * @brief Clear CAN Timestamp overrun flag
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_can_snap_ovr_clear(void)
++{
++ /* CLEAR the overrun bit */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_CCE_OFFSET, IOH_1588_CE_OVR);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_rx_snap_evt(void)
++ * @brief Receive Timestamp available
++ * @param None
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_rx_snap_evt(void)
++{
++ /* Is the rxs bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CE_OFFSET,
++ IOH_1588_CE_RXS);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn
++ * @brief Transmit Timestamp available
++ * @param None
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_tx_snap_evt(void)
++{
++ /* Is the txs bit SET? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CE_OFFSET,
++ IOH_1588_CE_TXS);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_rx_snap_evt_clear(void)
++ * @brief Clear Receive Timestamp available event
++ * @param None.
++ * @retval None.*/
++static INLINE void ioh_1588_rx_snap_evt_clear(void)
++{
++ /* CLEAR the rxs bit */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_CE_OFFSET, IOH_1588_CE_RXS);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_tx_snap_evt_clear(void)
++ * @brief Clear Transmit Timestamp available event
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_tx_snap_evt_clear(void)
++{
++ unsigned long ev_reg;
++
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CE_OFFSET, &ev_reg);
++ IOH_DEBUG
++ ("ioh_1588_tx_snap_evt_clear event reg content before clearing= %lx\n",
++ ev_reg);
++
++ /* CLEAR the txs bit */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_CE_OFFSET, IOH_1588_CE_TXS);
++
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CE_OFFSET, &ev_reg);
++ IOH_DEBUG
++ ("ioh_1588_tx_snap_evt_clear event reg content after clearing= %lx\n",
++ ev_reg);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_can_snap_get(
++ * unsigned long *rxs_low,unsigned long *rxs_high)
++ * @brief Get PTP CAN Port Timestamp value
++ * @param rxs_low [OUT] The CAN Rx low value.
++ * @param rxs_high [OUT] The CAN Rx high value.
++ * @retval None.
++*/
++static INLINE void
++ioh_1588_can_snap_get(unsigned long *rxs_low, unsigned long *rxs_high)
++{
++ /* Get the Receive Timestamp/Snapshot Low Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CXSL_OFFSET, rxs_low);
++
++ /* Get the Receive Timestamp/Snapshot High Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CXSH_OFFSET, rxs_high);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_rx_snap_get(
++ * unsigned long *rxs_low, unsigned long *rxs_high)
++ * @brief Get PTP Port Rx Timestamp value
++ * @param rxs_low [OUT] The Snap Rx value.
++ * @param rxs_high [OUT] The Snap Rx Value.
++ * @reatval None
++*/
++static INLINE void
++ioh_1588_rx_snap_get(unsigned long *rxs_low, unsigned long *rxs_high)
++{
++ /* Get the Receive Timestamp/Snapshot Low Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_RSL_OFFSET, rxs_low);
++
++ /* Get the Receive Timestamp/Snapshot High Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_RSH_OFFSET, rxs_high);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_tx_snap_get(
++ * unsigned long *txs_low, unsigned long *txs_high)
++ * @brief Get PTP Port Tx Timestamp value
++ * @param txs_low [OUT] The Port Tx value low.
++ * @param txs_high [OUT] The Port Tx value high.
++ * @retval None
++*/
++static INLINE void
++ioh_1588_tx_snap_get(unsigned long *txs_low, unsigned long *txs_high)
++{
++ /* Get the Transmit Timestamp/Snapshot Low Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_XSL_OFFSET, txs_low);
++
++ /* Get the Transmit Timestamp/Snapshot High Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_XSH_OFFSET, txs_high);
++
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_uuid_seqid_get(
++ * unsigned long *uuid_low,unsigned long *uuid_high, unsigned int *seq_id)
++ * @brief Get UUID High (16-bit value) & Sequence ID (16-bit value) of
++ * PTP message
++ * @param uuid_low [OUT] The UUID low value.
++ * @param seq_id [OUT] The sequence ID.
++ * @retval None.
++*/
++static INLINE void
++ioh_1588_uuid_seqid_get(unsigned long *uuid_low,
++ unsigned long *uuid_high, unsigned int *seq_id)
++{
++ unsigned long regval = 0;
++
++ /* Get the UUID Low Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_UID_OFFSET, uuid_low);
++
++ /* Get the Sequence ID and Source UUID High Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_SID_OFFSET, &regval);
++
++ *seq_id = (regval >> IOH_1588_SID_LOC);
++ *uuid_high = (regval & IOH_1588_LSB_SHORT_MASK);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_op_mode_set(unsigned long mode)
++ * @brief Sets the operation mode.
++ * @param mode [IN] The mode value.
++ * @retval None.
++*/
++static INLINE void ioh_1588_op_mode_set(unsigned long mode)
++{
++ unsigned long regval;
++
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CC_OFFSET, &regval);
++ regval =
++ (regval & ~IOH_1588_CC_MODE_MASK) | (mode <<
++ IOH_1588_CC_MODE_SHIFT);
++ /* set the operaion mode bits */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_CC_OFFSET, regval);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_op_mode_get(void)
++ * @brief Gets the operation mode.
++ * @param None.
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_op_mode_get(void)
++{
++ unsigned long regval;
++ unsigned long mode;
++
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CC_OFFSET, &regval);
++ /* get the operaion mode bits */
++ mode = (regval & IOH_1588_CC_MODE_MASK) >> IOH_1588_CC_MODE_SHIFT;
++
++ return mode;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_eth_enable_set(void)
++ * @brief Enbales the eth.
++ * @param None.
++ * @retval None.
++*/
++static INLINE void ioh_1588_eth_enable_set(void)
++{
++ /* SET the eth_enable bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_ECS_OFFSET, IOH_1588_ECS_ETH);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_eth_enable_clear(void)
++ * @brief Clears the eth enable.
++ * @param None.
++ * @retval None.
++*/
++static INLINE void ioh_1588_eth_enable_clear(void)
++{
++ /* Clear the eth_enable bit */
++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_ECS_OFFSET, IOH_1588_ECS_ETH);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_eth_enable_get(void)
++ * @brief Gets the eth enable.
++ * @param None.
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_eth_enable_get(void)
++{
++ /* Is eth_enable bit set? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_ECS_OFFSET,
++ IOH_1588_ECS_ETH);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_can_enable_set(void)
++ * @brief Sets the CAN enable.
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_can_enable_set(void)
++{
++ /* SET the can_enable bit */
++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_ECS_OFFSET, IOH_1588_ECS_CAN);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_can_enable_clear(void)
++ * @brief Sets the CAN enable clear
++ * @param None
++ * @retval None
++*/
++static INLINE void ioh_1588_can_enable_clear(void)
++{
++ /* Clear the can_enable bit */
++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_ECS_OFFSET, IOH_1588_ECS_CAN);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE unsigned long ioh_1588_can_enable_get(void)
++ * @brief Gets the CAN enable status.
++ * @param None.
++ * @retval unsigned long
++*/
++static INLINE unsigned long ioh_1588_can_enable_get(void)
++{
++ /* Is can_enable bit set? */
++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_ECS_OFFSET,
++ IOH_1588_ECS_CAN);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_station_set(unsigned long station,
++ * unsigned long value)
++ * @brief Set the station[1-6] address to be used in PTP message
++ * @param station [IN] The Station.
++ * @param value [IN] The Value.
++ * @retval None.
++*/
++static INLINE void
++ioh_1588_station_set(unsigned long station, unsigned long value)
++{
++ IOH_DEBUG("ioh_1588_station_set;setting station address=%lx\n", value);
++ /* Set the Station Address Register contents */
++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_STA_OFFSET +
++ station * sizeof(int), value);
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn static INLINE void ioh_1588_station_get (unsigned long station,
++ * unsigned long *value)
++ * @brief Get the station[1-6] address used in PTP message
++ * @param station [IN] The station.
++ * @param value [OUT] The value.
++ * @retval None.
++*/
++static INLINE void
++ioh_1588_station_get(unsigned long station, unsigned long *value)
++{
++ /* Get the Station Address Register contents */
++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_STA_OFFSET +
++ station * sizeof(int), value);
++ *value &= 0xFF; /* only one byte */
++}
++
++/**
++ * Support functions definitions
++ */
++
++/**
++ * @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_disable_interrupts(void)
++ * @brief Disables all interrupts on the 1588 device.
++ * @param None
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++
++enum ioh_status ioh_1588_disable_interrupts(void)
++{
++ if (ioh_1588_base != 0) {
++ IOH_DEBUG
++ ("ioh_1588_disable_interrupts:invoking \
++ ioh_1588_ttm_imask_clear\n");
++ ioh_1588_ttm_imask_clear();
++ IOH_DEBUG
++ ("ioh_1588_disable_interrupts:invoking \
++ ioh_1588_asms_imask_clear\n");
++ ioh_1588_asms_imask_clear();
++ IOH_DEBUG
++ ("ioh_1588_disable_interrupts:invoking \
++ ioh_1588_amms_imask_clear\n");
++ ioh_1588_amms_imask_clear();
++ IOH_DEBUG
++ ("ioh_1588_disable_interrupts:invoking \
++ ioh_1588_pps_imask_clear\n");
++ ioh_1588_pps_imask_clear();
++ }
++ return IOH_1588_SUCCESS;
++}
++
++/**
++ * @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_interrupt_pending(
++ * unsigned long *pending)
++ * @brief Check whether there is any pending interrupts from the 1588
++ * device.
++ * @param pending [IN] Pending flag which set to TRUE if there is any
++ * pending interrupt
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_interrupt_pending(unsigned long *pending)
++{
++ *pending = FALSE;
++ if (ioh_1588_pps_evt_get() || ioh_1588_amms_evt_get() ||
++ ioh_1588_asms_evt_get() || ioh_1588_ttm_evt_get()) {
++ IOH_DEBUG("ioh_1588_interrupt_pending:interrupt pending\n");
++ *pending = TRUE;
++ } else {
++ IOH_DEBUG("ioh_1588_interrupt_pending:NO interrupt pending\n");
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/**
++ * @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh1588PTPPortMode ioh_1588_port_mode_get(
++ * enum ioh1588PTPPort ptpPort)
++ * @brief Function to determine the port mode
++ * @param ptpPort [IN] Interested port (GBE_0)
++ * @retval enum ioh1588PTPPortMode
++ * - IOH_1588PTP_PORT_MASTER
++ * - IOH_1588PTP_PORT_SLAVE
++ * - IOH_1588PTP_PORT_ANYMODE
++ */
++enum ioh1588PTPPortMode ioh_1588_port_mode_get(enum ioh1588PTPPort ptpPort)
++{
++ /* Local variables */
++ unsigned long master_mode = FALSE;
++ unsigned long any_mode = FALSE;
++ enum ioh1588PTPPortMode port_mode = IOH_1588PTP_PORT_SLAVE;
++
++ /* Get the Mode of the PTP Port */
++ master_mode = ioh_1588_master_mode_get();
++ any_mode = ioh_1588_timestamp_all_get();
++
++ /* Is ANY mode (all message timestamp mode) on? */
++ if (TRUE == any_mode) {
++ IOH_DEBUG
++ ("ioh_1588_port_mode_get:all messages being timestamped\n");
++ /*
++ * When Any mode is set, all messages are time stamped,
++ * irrespective of the Master/Slave mode bit
++ */
++ port_mode = IOH_1588PTP_PORT_ANYMODE;
++ IOH_DEBUG
++ ("ioh_1588_port_mode_get:port_mode = \
++ IOH_1588PTP_PORT_ANYMODE\n");
++ } else {
++ /* Is Master mode on? */
++ if (TRUE == master_mode) {
++ port_mode = IOH_1588PTP_PORT_MASTER;
++ IOH_DEBUG
++ ("ioh_1588_port_mode_get:port_mode = \
++ IOH_1588PTP_PORT_MASTER\n");
++ } else {
++ port_mode = IOH_1588PTP_PORT_SLAVE;
++ IOH_DEBUG
++ ("ioh_1588_port_mode_get:port_mode = \
++ IOH_1588PTP_PORT_SLAVE\n");
++ }
++ }
++
++ return port_mode;
++}
++
++/*
++ * Public API definitions
++ */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_blpl_base_address_set(unsigned long base_addr)
++ *
++ * @brief Function sets the virtual address of registers
++ * @remarks This API will set the starting virtual addresses for the
++ * 1588 hardware registers. The main tasks performed by this
++ * function are:
++ * - If the aargument passed is NULL, return status
++ * IOH_1588_INVALIDPARAM
++ * - Set base address of IEEE 1588 registers to specified value
++ *
++ *
++ * @param base_addr [IN] - Virtual address of IEEE 1588 module registers
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid parameter passed
++ */
++enum ioh_status ioh_1588_blpl_base_address_set(unsigned long base_addr)
++{
++ if (!base_addr) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_blpl_base_address_set:invalid base address\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ ioh_1588_base = base_addr;
++ IOH_DEBUG("ioh_1588_blpl_base_address_set:base address=%lx\n",
++ ioh_1588_base);
++
++ /* Initialize the callback pointers */
++ ioh_tt_cbptr = (ioh1588TargetTimeCallback) NULL;
++ ioh_am_cbptr = (ioh1588AuxTimeCallback) NULL;
++ ioh_as_cbptr = (ioh1588AuxTimeCallback) NULL;
++ ioh_pps_cbptr = (ioh1588PulsePerSecondCallback) NULL;
++ IOH_DEBUG("ioh_1588_blpl_base_address_set:initialized callback ptrs\n");
++
++ /* Reset the statistics counters */
++ ioh_1588_stats.rxMsgs = ioh_1588_stats.txMsgs = 0;
++ IOH_DEBUG("ioh_1588_blpl_base_address_set:reset statistics counters\n");
++
++ /* Clear availability of various events */
++ IOH_DEBUG
++ ("ioh_1588_blpl_base_address_set:invoking \
++ ioh_1588_pps_evt_clear\n");
++ ioh_1588_pps_evt_clear();
++ IOH_DEBUG
++ ("ioh_1588_blpl_base_address_set:invoking \
++ ioh_1588_ttm_evt_clear\n");
++ ioh_1588_ttm_evt_clear();
++ IOH_DEBUG
++ ("ioh_1588_blpl_base_address_set:invoking \
++ ioh_1588_amms_evt_clear\n");
++ ioh_1588_amms_evt_clear();
++ IOH_DEBUG
++ ("ioh_1588_blpl_base_address_set:invoking \
++ ioh_1588_asms_evt_clear\n");
++ ioh_1588_asms_evt_clear();
++
++ IOH_DEBUG("ioh_1588_blpl_base_address_set:returning success\n");
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_port_config_set(
++ * enum ioh1588PTPPort ptpPort, enum ioh1588PTPPortMode ptpPortMode)
++ *
++ * @brief Configure IEEE 1588 Hardware Assist message detection on a given PTP
++ * port
++ *
++ * @remarks This API enables the time stamping on a particular PTP port.
++ * The main tasks performed by this function are:
++ * - Validate the parameters and return
++ * IOH_1588_INVALIDPARAM, if found invalid
++ * - Modify the TS_Channel_Control register to set the
++ * requested mode
++ *
++ *
++ * @param ptpPort [IN] - port on which PTP message detection to be enabled
++ * @param ptpPortMode [IN]- Master/Slave/All messages
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed
++ */
++enum ioh_status
++ioh_1588_ptp_port_config_set(enum ioh1588PTPPort ptpPort,
++ enum ioh1588PTPPortMode ptpPortMode)
++{
++ /* Verify the parameters for proper values */
++ if (ptpPort != IOH_1588_GBE_0_1588PTP_PORT) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ptp_port_config_set:invalid ptp port\
++ returning IOH_1588_GBE_0_1588PTP_PORT\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Set the Mode of the PTP Port */
++ switch (ptpPortMode) {
++ case IOH_1588PTP_PORT_MASTER:
++ {
++ IOH_DEBUG
++ ("ioh_1588_ptp_port_config_set:port_mode=\
++ IOH_1588PTP_PORT_MASTER\n");
++ IOH_DEBUG
++ ("ioh_1588_ptp_port_config_set:invoking \
++ ioh_1588_master_mode_set \
++ with param TRUE\n");
++ ioh_1588_master_mode_set(TRUE);
++ IOH_DEBUG
++ ("ioh_1588_ptp_port_config_set:invoking \
++ ioh_1588_timestamp_all_set \
++ with param FALSE\n");
++ ioh_1588_timestamp_all_set(FALSE);
++ break;
++ }
++ case IOH_1588PTP_PORT_SLAVE:
++ {
++ IOH_DEBUG
++ ("ioh_1588_ptp_port_config_set:port_mode=\
++ IOH_1588PTP_PORT_SLAVE\n");
++ IOH_DEBUG
++ ("ioh_1588_ptp_port_config_set:invoking \
++ ioh_1588_master_mode_set \
++ with param FALSE\n");
++ ioh_1588_master_mode_set(FALSE);
++ IOH_DEBUG
++ ("ioh_1588_ptp_port_config_set:invoking \
++ ioh_1588_timestamp_all_set \
++ with param FALSE\n");
++ ioh_1588_timestamp_all_set(FALSE);
++ break;
++ }
++ case IOH_1588PTP_PORT_ANYMODE:
++ {
++ IOH_DEBUG
++ ("ioh_1588_ptp_port_config_set:port_mode=\
++ IOH_1588PTP_PORT_ANYMODE\n");
++ IOH_DEBUG
++ ("ioh_1588_ptp_port_config_set:invoking \
++ ioh_1588_master_mode_set \
++ with param FALSE\n");
++ ioh_1588_master_mode_set(FALSE);
++ IOH_DEBUG
++ ("ioh_1588_ptp_port_config_set:invoking \
++ ioh_1588_timestamp_all_set \
++ with param TRUE\n");
++ ioh_1588_timestamp_all_set(TRUE);
++ break;
++ }
++ default:
++ {
++ IOH_LOG(KERN_ERR, "ioh_1588_ptp_port_config_set: \
++ Invalid Port Mode (%d) \
++ returning IOH_1588_INVALIDPARAM\n",
++ ptpPortMode);
++ return IOH_1588_INVALIDPARAM;
++ }
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_port_config_get(
++ * enum ioh1588PTPPort ptpPort,
++ * enum ioh1588PTPPortMode *ptpPortMode)
++ *
++ * @brief Get the configuration of IEEE 1588 Hardware Assist message
++ * detection
++ * for given PTP port
++ *
++ * @remarks This API retrieves the time stamping configuration of the given
++ * PTP port.
++ * The main tasks performed by this function are:
++ * - Validate the parameters and return
++ * IOH_1588_INVALIDPARAM, if found invalid
++ * - Return the current master/slave mode from
++ * TS_Channel_Control register
++ *
++ *
++ * @param ptpPort [IN] port for which PTP message configuration
++ * to be obtained
++ * @param ptpPortMode [OUT] Master/Slave/All messages
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed
++ */
++enum ioh_status
++ioh_1588_ptp_port_config_get(enum ioh1588PTPPort ptpPort,
++ enum ioh1588PTPPortMode *ptpPortMode)
++{
++ /* Verify the parameters for proper values */
++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) ||
++ ((enum ioh1588PTPPortMode *) NULL == ptpPortMode)) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ptp_port_config_get:\
++ invalid port_mode or port \
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Get the Mode of the PTP Port */
++ IOH_DEBUG
++ ("ioh_1588_ptp_port_config_get:invoking ioh_1588_port_mode_get\n");
++ *ptpPortMode = ioh_1588_port_mode_get(ptpPort);
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_rx_poll(
++ * enum ioh1588PTPPort ptpPort,
++ * struct ioh1588PtpMsgData *ptpMsgData)
++ *
++ * @brief Poll the IEEE 1588 Hardware Assist receive side message/time
++ * stamp
++ * detection status for given PTP Port
++ *
++ * @remarks This API will poll for the availability of a time stamp on the
++ * received Sync (in slave mode) or Delay_Req (in master mode)
++ * messages.
++ * The buffer is provided by the caller.
++ * The steps performed in this function are:
++ * - If ptpPort not valid or ptpMsgData is NULL return
++ * IOH_1588_INVALID_PARAM
++ * - Find out whether locked /unlocked mode.
++ * - If locked mode ,check the TS_Channel_Event register for Rx
++ * event
++ * - If locked mode, return NO TIMESTAMP if no Rx event flag is
++ * set.
++ * - Read the time stamp from RECV_Snapshot low, high and
++ * - SourceUUID0 low, high registers
++ * - Clear SourceUUId if the mode is not master/slave and PTP v1
++ * only.
++ * - Increment RX messages captured statistics counter
++ * - If locked mode ,clear the RX event is TS_Channel_Event
++ * register
++ *
++ *
++ * @param ptpPort [IN] port on which time stamp availability
++ * to be checked
++ * @param ptpMsgData [out] Captured time stamp and other message
++ * information
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed
++ * @li IOH_1588_NOTIMESTAMP - Time stamp not available
++ * @li IOH_1588_FAILED - Internal error occurred
++ */
++enum ioh_status
++ioh_1588_ptp_rx_poll(enum ioh1588PTPPort ptpPort, \
++ struct ioh1588PtpMsgData *ptpMsgData)
++{
++ unsigned long locked_mode = FALSE;
++
++ enum ioh1588PTPPortMode port_mode = IOH_1588PTP_PORT_MODE_INVALID;
++ enum ioh1588PTPVersion ptpVersion = IOH_1588PTP_VERSION_INVALID;
++ enum ioh1588PTPOperationMode opMode = IOH_1588PTP_OP_MODE_INVALID;
++
++ /* Verify the parameters for proper values */
++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) ||
++ ((struct ioh1588PtpMsgData *) NULL == ptpMsgData)) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ptp_rx_poll:invalid port or ptp message \
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /*Get the PTP version */
++ ptpVersion = ioh_1588_version_get();
++
++ /*check if locked/unlocked mode */
++ if (ptpVersion == IOH_1588PTP_VERSION_0) { /*PTP v1 only */
++ /* Get the Mode of the PTP Port if only PTPv1 is supported */
++ port_mode = ioh_1588_port_mode_get(ptpPort);
++ if (port_mode != IOH_1588PTP_PORT_ANYMODE)
++ locked_mode = TRUE;
++ } else { /*PTP v1 & v2 */
++
++ /*get operation mode */
++ opMode = ioh_1588_op_mode_get();
++ if ((opMode != IOH_1588PTP_OP_MODE_V1_ALL_MSGS) &&
++ (opMode != IOH_1588PTP_OP_MODE_V1_V2_ALL_MSGS)) {
++ locked_mode = TRUE;
++ }
++ }
++
++ /*if locked mode,check event flag */
++ if ((TRUE == locked_mode) && (TRUE != ioh_1588_rx_snap_evt())) {
++ IOH_DEBUG
++ ("ioh_1588_ptp_rx_poll:locked mode-event flag not set\n");
++ IOH_DEBUG("ioh_1588_ptp_rx_poll:NO TIMESTAMP \
++ returning IOH_1588_NOTIMESTAMP\n");
++ return IOH_1588_NOTIMESTAMP;
++ }
++
++ /* Fetch the receive timestamp */
++ IOH_DEBUG("ioh_1588_ptp_rx_poll:invoking ioh_1588_rx_snap_get\n");
++ ioh_1588_rx_snap_get(&ptpMsgData->ptpTimeStamp.timeValueLowWord,
++ &ptpMsgData->ptpTimeStamp.timeValueHighWord);
++
++ IOH_DEBUG
++ ("ioh_1588_ptp_rx_poll:ioh_1588_ptp_rx_poll Snapshot (Hi:Low): \
++ %lx : %lx\n",
++ ptpMsgData->ptpTimeStamp.timeValueHighWord,
++ ptpMsgData->ptpTimeStamp.timeValueLowWord);
++
++ /* Fetch the UUID & Seq# of PTP messages in 'Master/Slave Mode' only */
++ if ((TRUE == locked_mode) && (IOH_1588PTP_VERSION_0 == ptpVersion)) {
++ IOH_DEBUG
++ ("ioh_1588_ptp_rx_poll:invoking ioh_1588_uuid_seqid_get\n");
++ ioh_1588_uuid_seqid_get(&ptpMsgData->ptpUuid.uuidValueLowWord,
++ &ptpMsgData->ptpUuid.
++ uuidValueHighHalfword,
++ &ptpMsgData->ptpSequenceNumber);
++ }
++ /* Clear-off the UUID & Seq# of all the messages in 'Any Mode' */
++ else {
++ IOH_DEBUG
++ ("ioh_1588_ptp_rx_poll:port mode is ANYMODE,clearing off \
++ UUID & SeqNumber\n");
++ ptpMsgData->ptpUuid.uuidValueLowWord = 0;
++ ptpMsgData->ptpUuid.uuidValueHighHalfword = 0;
++ ptpMsgData->ptpSequenceNumber = 0;
++ }
++
++ /* Increment receive timestamp counter
++ * Note:In unlocked modes,this will get incremented
++ * for every rx time stamp poll.
++ */
++ ioh_1588_stats.rxMsgs++;
++ IOH_DEBUG("ioh_1588_ptp_rx_poll:incremented rcv timestamp \
++ counter=%ld\n", ioh_1588_stats.rxMsgs);
++
++ /*
++ * Fill-in the PTP message type.This can be done
++ * only when PTP v1 alone is supported and mode
++ * is master/slave.Set the message type as unknown
++ * for all other cases.
++ */
++ if (ptpVersion == IOH_1588PTP_VERSION_0) { /*PTP v1 only */
++ switch (port_mode) {
++ case IOH_1588PTP_PORT_MASTER:
++ {
++ IOH_DEBUG
++ ("ioh_1588_ptp_rx_poll:PTP message type=\
++ IOH_1588PTP_MSGTYPE_DELAYREQ\n");
++ ptpMsgData->ptpMsgType =
++ IOH_1588PTP_MSGTYPE_DELAYREQ;
++ break;
++ }
++ case IOH_1588PTP_PORT_SLAVE:
++ {
++ IOH_DEBUG
++ ("ioh_1588_ptp_rx_poll:PTP message type=\
++ IOH_1588PTP_MSGTYPE_SYNC\n");
++ ptpMsgData->ptpMsgType =
++ IOH_1588PTP_MSGTYPE_SYNC;
++ break;
++ }
++ case IOH_1588PTP_PORT_ANYMODE:
++ {
++ IOH_DEBUG
++ ("ioh_1588_ptp_rx_poll:PTP message type=\
++ IOH_1588PTP_MSGTYPE_UNKNOWN\n");
++ ptpMsgData->ptpMsgType =
++ IOH_1588PTP_MSGTYPE_UNKNOWN;
++ break;
++ }
++ default:
++ {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ptp_rx_poll(): Invalid Port \
++ Mode \
++ returning IOH_1588_FAILED\n");
++ return IOH_1588_FAILED;
++ }
++ }
++ } else { /*PTP v1 & v2 */
++
++ IOH_DEBUG
++ ("ioh_1588_ptp_rx_poll:PTP message type=\
++ IOH_1588PTP_MSGTYPE_UNKNOWN\n");
++ ptpMsgData->ptpMsgType = IOH_1588PTP_MSGTYPE_UNKNOWN;
++ }
++
++ /* If locked mode allow next timestamp to be captured */
++ if (TRUE == locked_mode) {
++ IOH_DEBUG
++ ("ioh_1588_ptp_rx_poll:invoking \
++ ioh_1588_rx_snap_evt_clear\n");
++ ioh_1588_rx_snap_evt_clear();
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_tx_poll(
++ * enum ioh1588PTPPort ptpPort,
++ * struct ioh1588PtpMsgData *ptpMsgData)
++ *
++ * @brief Poll the IEEE 1588 Hardware Assist transmit side message/time
++ * stamp
++ * detection status for given PTP Port
++ *
++ * @remarks This API will poll for the availability of a time stamp on the
++ * transmit side Sync (in master mode) or Delay_Req (in slave mode)
++ * messages.
++ * The buffer is provided by the caller.
++ * The main tasks performed by this function are:
++ * - If ptpPort not valid or ptpMsgData is NULL
++ * return IOH_1588_INVALID_PARAM
++ * - Find out whether locked /unlocked mode.
++ * - If locked mode ,check the TS_Channel_Event register for Tx
++ * event
++ * - If locked mode, return NO TIMESTAMP if no Tx event flag is
++ * set.
++ * - Read the time stamp from XMIT_Snapshot low, high registers
++ * - Increment TX messages captured statistics counter
++ * - If locked mode, clear the TX event is TS_Channel_Event
++ * register
++ *
++ *
++ * @param ptpPort [IN] port on which time stamp availability to be
++ * checked
++ * @param ptpMsgData [OUT] Captured time stamp and other message
++ * information
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed
++ * @li IOH_1588_NOTIMESTAMP - Time stamp not available
++ * @li IOH_1588_FAILED - Internal error occurred
++ */
++enum ioh_status
++ioh_1588_ptp_tx_poll(enum ioh1588PTPPort ptpPort, \
++ struct ioh1588PtpMsgData *ptpMsgData)
++{
++ unsigned long locked_mode = FALSE;
++
++ enum ioh1588PTPPortMode port_mode = IOH_1588PTP_PORT_MODE_INVALID;
++ enum ioh1588PTPVersion ptpVersion = IOH_1588PTP_VERSION_INVALID;
++ enum ioh1588PTPOperationMode opMode = IOH_1588PTP_OP_MODE_INVALID;
++
++ /* Verify the parameters for proper values */
++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) ||
++ ((struct ioh1588PtpMsgData *) NULL == ptpMsgData)) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ptp_tx_poll:invalid port or ptp message \
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /*Get the PTP version */
++ ptpVersion = ioh_1588_version_get();
++
++ /*check if locked/unlocked mode */
++ if (ptpVersion == IOH_1588PTP_VERSION_0) { /*PTP v1 only */
++ /* Get the Mode of the PTP Port if only PTPv1 is supported */
++ port_mode = ioh_1588_port_mode_get(ptpPort);
++ if (port_mode != IOH_1588PTP_PORT_ANYMODE)
++ locked_mode = TRUE;
++ } else { /*PTP v1 & v2 */
++
++ /*get operation mode */
++ opMode = ioh_1588_op_mode_get();
++ if ((opMode != IOH_1588PTP_OP_MODE_V1_ALL_MSGS) &&
++ (opMode != IOH_1588PTP_OP_MODE_V1_V2_ALL_MSGS)) {
++ locked_mode = TRUE;
++ }
++ }
++
++ /*if locked mode,check event flag */
++ if ((TRUE == locked_mode) && (TRUE != ioh_1588_tx_snap_evt())) {
++ IOH_DEBUG
++ ("ioh_1588_ptp_tx_poll:locked mode-event flag not set\n");
++ IOH_DEBUG
++ ("ioh_1588_ptp_tx_poll:ioh_1588_ptp_tx_poll NO TIMESTAMP \
++ returning IOH_1588_NOTIMESTAMP\n");
++ return IOH_1588_NOTIMESTAMP;
++ }
++
++ /* read time stamp registers */
++ ioh_1588_tx_snap_get(&ptpMsgData->ptpTimeStamp.timeValueLowWord,
++ &ptpMsgData->ptpTimeStamp.timeValueHighWord);
++
++ IOH_DEBUG
++ ("ioh_1588_ptp_tx_poll:ioh_1588_ptp_tx_poll Snapshot (Hi:Low): \
++ %lx : %lx\n",
++ ptpMsgData->ptpTimeStamp.timeValueHighWord,
++ ptpMsgData->ptpTimeStamp.timeValueLowWord);
++ /*
++ * Fill the UUID and Seq# with invalid values (zeros)
++ * since they are not relevant for transmit timestamp
++ */
++ ptpMsgData->ptpUuid.uuidValueLowWord = 0;
++ ptpMsgData->ptpUuid.uuidValueHighHalfword = 0;
++ ptpMsgData->ptpSequenceNumber = 0;
++
++ /*
++ * Increment transmit timestamp counter
++ * Note:In unlocked modes,this will get incremented
++ * for every tx time stamp poll
++ */
++ ioh_1588_stats.txMsgs++;
++ IOH_DEBUG("ioh_1588_ptp_tx_poll:incremented tx timestamp counter=%ld\n",
++ ioh_1588_stats.txMsgs);
++
++ /*
++ * Fill-in the PTP message type.This can be done
++ * only when PTP v1 alone is supported and mode
++ * is master/slave.Set the message type as unknown
++ * for all other cases.
++ */
++ if (ptpVersion == IOH_1588PTP_VERSION_0) { /*PTP v1 only */
++ switch (port_mode) {
++ case IOH_1588PTP_PORT_MASTER:
++ {
++ IOH_DEBUG
++ ("ioh_1588_ptp_tx_poll:PTP message type=\
++ IOH_1588PTP_MSGTYPE_SYNC\n");
++ ptpMsgData->ptpMsgType =
++ IOH_1588PTP_MSGTYPE_SYNC;
++ break;
++ }
++ case IOH_1588PTP_PORT_SLAVE:
++ {
++ IOH_DEBUG
++ ("ioh_1588_ptp_tx_poll:PTP message type=\
++ IOH_1588PTP_MSGTYPE_DELAYREQ\n");
++ ptpMsgData->ptpMsgType =
++ IOH_1588PTP_MSGTYPE_DELAYREQ;
++ break;
++ }
++ case IOH_1588PTP_PORT_ANYMODE:
++ {
++ IOH_DEBUG
++ ("ioh_1588_ptp_tx_poll:PTP message type=\
++ IOH_1588PTP_MSGTYPE_UNKNOWN\n");
++ ptpMsgData->ptpMsgType =
++ IOH_1588PTP_MSGTYPE_UNKNOWN;
++ break;
++ }
++ default:
++ {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ptp_tx_poll(): \
++ Invalid Port Mode \
++ returning IOH_1588_FAILED\n");
++ return IOH_1588_FAILED;
++ }
++ }
++ } else { /*PTP v1 & v2 */
++
++ IOH_DEBUG
++ ("ioh_1588_ptp_tx_poll:PTP message type=\
++ IOH_1588PTP_MSGTYPE_UNKNOWN\n");
++ ptpMsgData->ptpMsgType = IOH_1588PTP_MSGTYPE_UNKNOWN;
++ }
++
++ /* If locked mode allow next timestamp to be captured */
++ if (locked_mode) {
++ IOH_DEBUG
++ ("ioh_1588_ptp_tx_poll:invoking ioh_1588_tx_snap_evt_clear\n");
++ ioh_1588_tx_snap_evt_clear();
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_system_time_set(
++ * struct ioh1588TimeValue systemTime)
++ *
++ * @brief This API sets the system time to given value
++ * @remarks Sets the System Time in the IEEE 1588 hardware assist block.
++ *
++ * @param systemTime [IN] value to set the system time to
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_system_time_set(struct ioh1588TimeValue systemTime)
++{
++ unsigned long old_fsv = 0;
++
++ /* Retrieve old Frequency Scaling Value */
++ IOH_DEBUG("ioh_1588_system_time_set:invoking ioh_1588_addend_get\n");
++ ioh_1588_addend_get(&old_fsv);
++ IOH_DEBUG("ioh_1588_system_time_set:existing freq scaling value=%lx\n",
++ old_fsv);
++
++ /*
++ * Set the Frequency Scaling Value to zero (0) so that
++ * System Time doesn't get incremented while it is being written to
++ */
++ IOH_DEBUG("ioh_1588_system_time_set:invoking ioh_1588_addend_set \
++ to set frequncy scaling value to 0\n");
++ ioh_1588_addend_set(0);
++
++ /* Update System Time with user specified values */
++ IOH_DEBUG("ioh_1588_system_time_set:invoking \
++ ioh_1588_ioh_1588_sys_snap_set \
++ with values low=%lx,high=%lx\n",
++ systemTime.timeValueLowWord, systemTime.timeValueHighWord);
++ ioh_1588_sys_snap_set(systemTime.timeValueLowWord,
++ systemTime.timeValueHighWord);
++
++ /*
++ * Let the hardware assist re-evaluate the target time reached
++ * condition based on the new system time
++ */
++ IOH_DEBUG("ioh_1588_system_time_set:invoking ioh_1588_ttm_evt_clear\n");
++ ioh_1588_ttm_evt_clear();
++
++ /*
++ * Restore old Frequency Scaling Value so that System Time
++ * can be incremented
++ */
++ IOH_DEBUG("ioh_1588_system_time_set:invoking ioh_1588_addend_set \
++ to restore freq scaling value\n");
++ ioh_1588_addend_set(old_fsv);
++
++ IOH_DEBUG("ioh_1588_system_time_set:returning IOH_1588_SUCCESS\n");
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_system_time_get(
++ * struct ioh1588TimeValue *systemTime)
++ *
++ * @brief Gets the System Time from the IEEE 1588 hardware assist block
++ * @remarks This API gets the System time.
++ * The main steps followed in this function are:
++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL
++ * - Return the current system time by reading the SystemTime low,
++ * high registers
++ *
++ *
++ * @param systemTime [OUT] - Address to which system time is to be
++ * returned
++ *
++ * @return enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid address passed
++ */
++enum ioh_status ioh_1588_system_time_get(struct ioh1588TimeValue *systemTime)
++{
++ /* Verify the parameter */
++ if ((struct ioh1588TimeValue *) NULL == systemTime) {
++ IOH_LOG(KERN_ERR, "ioh_1588_system_time_get:invalid parameter \
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Fetch System Time */
++ ioh_1588_sys_snap_get(&systemTime->timeValueLowWord,
++ &systemTime->timeValueHighWord);
++
++ IOH_DEBUG("ioh_1588_system_time_get:invoked \
++ ioh_1588_ioh_1588_sys_snap_get \
++ system time:low=%lx,high=%lx\n",
++ systemTime->timeValueLowWord, systemTime->timeValueHighWord);
++ IOH_DEBUG("ioh_1588_system_time_get returning IOH_1588_SUCCESS\n");
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_tick_rate_set(unsigned long tickRate)
++ *
++ * @brief Sets the Frequency Scaling Value in the IEEE 1588 hardware
++ * assist block
++ *
++ * @remarks This API sets the Tick Rate (Frequency Scaling Value) in the
++ * IEEE 1588 block. This value determines the progress at which
++ * the System time advances.
++ * Note: For the A1 hardware sample, the addend register value
++ * configured in the hardware
++ * is calculated as follows:
++ * Addend register value = Logical right shift tickRate by 1 and
++ * set MSB to 1
++ *
++ * @param tickRate [IN] Frequency scaling value
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_tick_rate_set(unsigned long tickRate)
++{
++ /* Update the Frequency Scaling Value */
++#ifdef IOH_IEEE1588_A1_SAMPLE_BUG
++ /*back up tick rate provided by app */
++ gTickRateApp = tickRate;
++ /*calculate actual tick rate for device */
++ IOH_DEBUG("ioh_1588_tick_rate_set:tick rate [app]=%lx\n", tickRate);
++ tickRate = ((tickRate >> 1) | 0x80000000);
++ IOH_DEBUG("ioh_1588_tick_rate_set:tick rate [dev]=%lx\n", tickRate);
++#endif
++ IOH_DEBUG("ioh_1588_tick_rate_set:invoking ioh_1588_addend_set \
++ with tick rate=%lx\n", tickRate);
++ ioh_1588_addend_set(tickRate);
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_tick_rate_get(unsigned long *tickRate)
++ *
++ * @brief Gets the Frequency Scaling Value from the IEEE 1588 hardware
++ * assist block
++ *
++ * @remarks This API gets the Tick Rate (Frequency Scaling Value) used in
++ * the IEEE 1588 block.
++ * This value determines the progress at which the System time
++ * advances.
++ * The main steps followed in this function are:
++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL
++ * - Return the content of Addend register
++ *
++ *
++ * @param tickRate [IN] - Address where current Frequency scaling value is
++ * returned
++ *
++ * @return enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARM - Invalid address passed
++ */
++enum ioh_status ioh_1588_tick_rate_get(unsigned long *tickRate)
++{
++ /* Verify the parameter */
++ if ((unsigned long *)NULL == tickRate) {
++ IOH_LOG(KERN_ERR, "ioh_1588_tick_rate_get:invalid tick rate\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++#ifdef IOH_IEEE1588_A1_SAMPLE_BUG
++ /* Retrieve Frequency Scaling Value stored in software buffer */
++ *tickRate = gTickRateApp;
++#else
++ /* Retrieve Current Frequency Scaling Value */
++ ioh_1588_addend_get(tickRate);
++#endif
++ IOH_DEBUG("ioh_1588_tick_rate_get:invoked ioh_1588_addend_get\
++ the tick rate=%lx\n", *tickRate);
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_target_time_interrupt_enable(
++ * ioh1588TargetTimeCallback callBack)
++ *
++ * @brief Enable the target time reached/exceeded system time interrupt
++ *
++ * @remarks This API enables the interrupt that occurs when the System time
++ * reaches the Target time set in the IEEE 1588 hardware assist
++ * block.
++ * The main steps followed in this function are:
++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL
++ * - Modify Time Sync Control Register to enable target time
++ * interrupt
++ * - Set the handler to callback function provided
++ *
++ *
++ * @param callBack [IN] - Routine to be invoked when target time reached
++ * interrupt occurs
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Null parameter passed for callback
++ */
++enum ioh_status
++ioh_1588_target_time_interrupt_enable(ioh1588TargetTimeCallback callBack)
++{
++ /* Verify the parameter */
++ if ((ioh1588TargetTimeCallback) NULL == callBack) {
++ IOH_LOG(KERN_ERR, "ioh_1588_target_time_interrupt_enable\
++ invalid callback;returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Register the Callback */
++ ioh_tt_cbptr = callBack;
++
++ /* Set target time interrupt mask */
++ IOH_DEBUG("ioh_1588_target_time_interrupt_enable:invoking\
++ ioh_1588_ttm_imask_set\n");
++ ioh_1588_ttm_imask_set();
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_target_time_interrupt_disable(void)
++ *
++ * @brief Disable the target time reached/exceeded system time interrupt
++ *
++ * @remarks This API disables the interrupt that occurs when the System time
++ * reaches the Target time set in the IEEE 1588 hardware assist
++ * block.
++ * The main steps followed in this function are:
++ * - Modify Time Sync Control Register to disable target time
++ * interrupt
++ * - Clear the callback handler
++ *
++ * @param None
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_target_time_interrupt_disable(void)
++{
++ /* Clear target time interrupt mask */
++ IOH_DEBUG("ioh_1588_target_time_interrupt_disable:invoking \
++ ioh_1588_ttm_imask_clear\n");
++ ioh_1588_ttm_imask_clear();
++
++ /* Unregister the Callback */
++ ioh_tt_cbptr = (ioh1588TargetTimeCallback) NULL;
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_target_time_poll(
++ * unsigned long *ttmPollFlag, struct ioh1588TimeValue *targetTime)
++ *
++ * @brief Poll to verify whether the System time is greater or equal
++ * to the Target time in the IEEE 1588 hardware assist block.
++ *
++ * @remarks The main steps followed in this function are:
++ * - Validate the parameters and return IOH_1588_INVALIDPARAM, if
++ * not valid
++ * - If callback function registered, return status
++ * IOH_1588_INTERRUPTMODEINUSE
++ * - Read the TS_Event register to check for the presence of valid
++ * snapshot
++ * - Read the TargetTimeSnap low, high registers
++ * - Clear the event from TS_Event register
++ *
++ *
++ * @param ttmPollFlag [OUT] TRUE if target time has reached system
++ * time
++ * FALSE if target time has not reached
++ * system time
++ * @param targetTime [OUT] Snap shot of target time captured
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Null parameter passed
++ * @li IOH_1588_INTERRUPTMODEINUSE - Interrupt mode is in use
++ */
++enum ioh_status
++ioh_1588_target_time_poll(unsigned long *ttmPollFlag,
++ struct ioh1588TimeValue *targetTime)
++{
++ /* Verify the parameters */
++ if (((unsigned long *)NULL == ttmPollFlag) ||
++ ((struct ioh1588TimeValue *) NULL == targetTime)) {
++ IOH_LOG(KERN_ERR, "ioh_1588_target_time_poll: invalid param\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Is interrupt mode of processing is enabled? */
++ if ((ioh1588TargetTimeCallback) NULL != ioh_tt_cbptr) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_target_time_poll:returning \
++ IOH_1588_INTERRUPTMODEINUSE\n");
++ return IOH_1588_INTERRUPTMODEINUSE;
++ }
++
++ /* Is the System Time reached or exceeded Target Time? */
++ *ttmPollFlag = ioh_1588_ttm_evt_get();
++ if (FALSE == *ttmPollFlag) {
++ IOH_DEBUG
++ ("ioh_1588_target_time_poll:target time not reached\n");
++ /* Target Time not to be returned yet */
++ targetTime->timeValueLowWord = 0;
++ targetTime->timeValueHighWord = 0;
++
++ return IOH_1588_SUCCESS;
++ }
++
++ IOH_DEBUG("ioh_1588_target_time_poll:target time reached\n");
++ /* Get the Target Time */
++ ioh_1588_tgt_snap_get(&targetTime->timeValueLowWord,
++ &targetTime->timeValueHighWord);
++
++ IOH_DEBUG("ioh_1588_target_time_poll:target time:low=%lx high=%lx\n",
++ targetTime->timeValueLowWord, targetTime->timeValueHighWord);
++
++ IOH_DEBUG
++ ("ioh_1588_target_time_poll:invoking ioh_1588_ttm_evt_clear\n");
++ /* Clear the target time reached condition (ttipend bit) */
++ ioh_1588_ttm_evt_clear();
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_target_time_set(
++ * struct ioh1588TimeValue targetTime)
++ *
++ * @brief Sets the Target Time in the IEEE 1588 hardware assist block
++ *
++ * @remarks This API will set the Target Time to a given value.
++ *
++ * @param targetTime [IN] - Target time to set
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_target_time_set(struct ioh1588TimeValue targetTime)
++{
++ unsigned long old_mask = FALSE;
++
++ /* Retrieve existing target time interrupt mask value */
++ old_mask = ioh_1588_ttm_imask_get();
++ IOH_DEBUG("ioh_1588_target_time_set:target time interrupt mask=%lx\n",
++ old_mask);
++
++ /*
++ * Clear the target time interrupt mask so that the interrupt will not
++ * come
++ * during the time we manipulate the registers.
++ */
++ IOH_DEBUG("ioh_1588_target_time_set:invoking ioh_1588_ttm_imask_clear\
++ to clear the target time interrupt mask\n");
++ ioh_1588_ttm_imask_clear();
++
++ IOH_DEBUG("ioh_1588_target_time_set:invoking ioh_1588_tgt_snap_set \
++ with values:low=%lx,high=%lx\n", \
++ targetTime.timeValueLowWord, targetTime.timeValueHighWord);
++ /* Update Target Time with user specified values */
++ ioh_1588_tgt_snap_set(targetTime.timeValueLowWord,
++ targetTime.timeValueHighWord);
++
++ /*
++ * Let the hardware assist re-evaluate the target time reached
++ * condition based on the new target time
++ */
++ IOH_DEBUG("ioh_1588_target_time_set:invoking ioh_1588_ttm_evt_clear\n");
++ ioh_1588_ttm_evt_clear();
++
++ /* Restore the preserved target time interrupt mask value */
++ if (TRUE == old_mask) {
++ IOH_DEBUG
++ ("ioh_1588_target_time_set:invoking \
++ ioh_1588_ttm_imask_set\n");
++ ioh_1588_ttm_imask_set();
++ }
++
++ IOH_DEBUG("ioh_1588_target_time_set:returning IOH_1588_SUCCESS\n");
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_target_time_get(
++ * struct ioh1588TimeValue *targetTime)
++ *
++ * @brief Gets the Target Time in the IEEE 1588 hardware assist block
++ *
++ * @remarks This API will get the Target Time from IEEE 1588 block
++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL
++ * - Read and return the content of TargetTime low, high registers
++ *
++ *
++ * @param targetTime [IN] - Address to which target time is to be returned
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Null parameter passed
++ */
++enum ioh_status ioh_1588_target_time_get(struct ioh1588TimeValue *targetTime)
++{
++ /* Verify the parameter */
++ if ((struct ioh1588TimeValue *) NULL == targetTime) {
++ IOH_DEBUG("ioh_1588_target_time_get:invalid param \
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Get Target Time */
++ ioh_1588_tgt_snap_get(&targetTime->timeValueLowWord,
++ &targetTime->timeValueHighWord);
++ IOH_DEBUG("ioh_1588_target_time_get:invoked ioh_1588_tgt_snap_get \
++ target time:low=%lx,high:%lx\n", \
++ targetTime->timeValueLowWord, targetTime->timeValueHighWord);
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_time_interrupt_enable(
++ * enum ioh1588AuxMode auxMode,ioh1588AuxTimeCallback callBack)
++ *
++ * @brief Enables the interrupt for the Auxiliary Master/Slave mode for
++ * Time
++ * Stamp in the IEEE 1588 hardware assist block
++ *
++ * @remarks This API will enable the Auxiliary Master/Slave
++ * Time stamp Interrupt. The main steps followed in
++ * this function are:
++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL
++ * - Modify the Time Sync Controller register to enable the
++ * interrupt
++ * - Set the callback routine
++ *
++ *
++ * @param auxMode [IN] - Auxiliary slave or master mode
++ * @param callBack [IN] - Callback to be invoked when interrupt
++ * fires
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Null parameter passed
++ */
++enum ioh_status
++ioh_1588_aux_time_interrupt_enable(enum ioh1588AuxMode auxMode,
++ ioh1588AuxTimeCallback callBack)
++{
++ /* Verify the parameters */
++ if ((IOH_1588_AUXMODE_INVALID <= auxMode) ||
++ ((ioh1588AuxTimeCallback) NULL == callBack)) {
++ IOH_DEBUG("ioh_1588_aux_time_interrupt_enable:invalid param \
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Register the Callback and SET the amm/asm bits on */
++ if (IOH_1588_AUXMODE_MASTER == auxMode) {
++ IOH_DEBUG
++ ("ioh_1588_aux_time_interrupt_enable:IOH_1588_AUXMODE_MASTER \
++ invoking ioh_1588_amms_imask_set\n");
++ ioh_am_cbptr = callBack;
++ ioh_1588_amms_imask_set();
++
++ } else {
++ IOH_DEBUG
++ ("ioh_1588_aux_time_interrupt_enable:IOH_1588_AUXMODE_SLAVE \
++ invoking ioh_1588_asms_imask_set\n");
++ ioh_as_cbptr = callBack;
++ ioh_1588_asms_imask_set();
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_time_interrupt_disable(
++ * enum ioh1588AuxMode auxMode)
++ *
++ * @brief Disables the interrupt for the Auxiliary Master/Slave mode for
++ * Time
++ * Stamp in the IEEE 1588 hardware assist block
++ *
++ * @remarks This API will disable the Auxiliary Master/Slave
++ * Time stamp Interrupt. The main steps followed in this
++ * function are:
++ * - Return IOH_1588_INVALIDPARAM if auxMode passed is not valid
++ * - Modify the Time Sync Controller register to disable the
++ * interrupt
++ * - Clear the callback handler
++ *
++ *
++ * @param auxMode [IN] - Auxiliary slave or master mode
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid mode specified
++ */
++enum ioh_status ioh_1588_aux_time_interrupt_disable(enum ioh1588AuxMode auxMode)
++{
++ /* Verify the parameters */
++ if (IOH_1588_AUXMODE_INVALID <= auxMode) {
++ IOH_DEBUG("ioh_1588_aux_time_interrupt_disable:invalid param \
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ if (IOH_1588_AUXMODE_MASTER == auxMode) {
++ IOH_DEBUG
++ ("ioh_1588_aux_time_interrupt_disable:\
++ IOH_1588_AUXMODE_MASTER\
++ invoking ioh_1588_amms_imask_clear\n");
++ ioh_1588_amms_imask_clear();
++ ioh_am_cbptr = (ioh1588AuxTimeCallback) NULL;
++ } else {
++ IOH_DEBUG
++ ("ioh_1588_aux_time_interrupt_disable:\
++ IOH_1588_AUXMODE_SLAVE\
++ invoking ioh_1588_asms_imask_clear\n");
++ ioh_1588_asms_imask_clear();
++ ioh_as_cbptr = (ioh1588AuxTimeCallback) NULL;
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_time_poll(
++ * enum ioh1588AuxMode auxMode, unsigned long *pollFlag,
++ * struct ioh1588TimeValue*auxTime)
++ *
++ * @brief Poll for the Auxiliary Time Stamp captured event for the mode
++ * requested
++ *
++ * @remarks Polls for the Time stamp in the appropriate Auxiliary Snapshot
++ * Registers based on the mode specified. Return true and
++ * the contents of the Auxiliary snapshot if it is available
++ * otherwise return false. The main steps followed in this function
++ * are:
++ * - Validate the parameters and return IOH_1588_INVALIDPARAM if
++ * found invalid
++ * - If callbacks registered, return status
++ * IOH_1588_INTERRUPTMODEINUSE
++ * - Read the TS_Event register to check for the presence of valid
++ * snapshot
++ * - If the event is not set, return status IOH_1588_NOTIMESTAMP
++ * - Read the AuxSlaveModeSnap or AuxMasterModeSnap low, high
++ * registers depending on the auxMode
++ * - Clear the event from TS_Event register
++ *
++ *
++ * @param auxMode [IN] Auxiliary Snapshot Register
++ * (Master/Slave) to be checked
++ * @param pollFlag [OUT] TRUE if time stamp captured in aux
++ * snapshot register
++ * FALSE if the time stamp not captured
++ * @param auxTime [OUT] Buffer for returning captured Auxiliary
++ * Snapshot time
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid parameter passed
++ * @li IOH_1588_INTERRUPTMODEINUSE - Interrupt mode is in use
++ */
++enum ioh_status
++ioh_1588_aux_time_poll(enum ioh1588AuxMode auxMode, unsigned long *pollFlag,
++ struct ioh1588TimeValue *auxTime)
++{
++ unsigned long ammsFlag = FALSE;
++ unsigned long asmsFlag = FALSE;
++
++ /* Verify the parameters */
++ if (((unsigned long *)NULL == pollFlag) ||
++ (IOH_1588_AUXMODE_INVALID <= auxMode) ||
++ ((struct ioh1588TimeValue *) NULL == auxTime)) {
++ IOH_DEBUG("ioh_1588_aux_time_poll:invalid param \
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Get Auxiliary Master/Slave Mode Snapshot */
++ if (IOH_1588_AUXMODE_MASTER == auxMode) {
++ IOH_DEBUG("ioh_1588_aux_time_poll:IOH_1588_AUXMODE_MASTER\n");
++ /* Is interrupt mode of processing is enabled? */
++ if ((ioh1588AuxTimeCallback) NULL != ioh_am_cbptr) {
++ IOH_DEBUG
++ ("ioh_1588_aux_time_poll:interrupt mode in use\n");
++ return IOH_1588_INTERRUPTMODEINUSE;
++ }
++
++ /* Is the Auxiliary Master Mode Snapshot available? */
++ ammsFlag = ioh_1588_amms_evt_get();
++ if (FALSE == ammsFlag) {
++ IOH_DEBUG("ioh_1588_aux_time_poll:NO Auxiliary Master \
++ Mode Snapshot available\n");
++ *pollFlag = FALSE;
++ auxTime->timeValueLowWord = 0;
++ auxTime->timeValueHighWord = 0;
++ return IOH_1588_SUCCESS;
++ }
++
++ /* Get Auxiliary Master Snapshot */
++ ioh_1588_aux_master_snap_get(&auxTime->timeValueLowWord,
++ &auxTime->timeValueHighWord);
++ IOH_DEBUG("ioh_1588_aux_time_poll:Auxiliary Master Snapshot \
++ low=%lx,high=%lx\n", auxTime->timeValueLowWord, \
++ auxTime->timeValueHighWord);
++
++ *pollFlag = TRUE;
++
++ /* Clear the snapshot availability condition */
++ IOH_DEBUG
++ ("ioh_1588_aux_time_poll:invoking ioh_1588_amms_evt_clear\n");
++ ioh_1588_amms_evt_clear();
++ } else { /* IOH_1588_AUXMODE_SLAVE == auxMode */
++
++ IOH_DEBUG("ioh_1588_aux_time_poll:IOH_1588_AUXMODE_SLAVE\n");
++ /* Is interrupt mode of processing is enabled? */
++ if ((ioh1588AuxTimeCallback) NULL != ioh_as_cbptr) {
++ IOH_DEBUG
++ ("ioh_1588_aux_time_poll:interrupt mode in use\n");
++ return IOH_1588_INTERRUPTMODEINUSE;
++ }
++
++ /* Is the Auxiliary Slave Mode Snapshot available? */
++ asmsFlag = ioh_1588_asms_evt_get();
++ if (FALSE == asmsFlag) {
++ IOH_DEBUG("ioh_1588_aux_time_poll:NO Auxiliary Slave \
++ Mode Snapshot available\n");
++ *pollFlag = FALSE;
++ auxTime->timeValueLowWord = 0;
++ auxTime->timeValueHighWord = 0;
++ return IOH_1588_SUCCESS;
++ }
++
++ /* Get Auxiliary Slave Snapshot */
++ ioh_1588_aux_slave_snap_get(&auxTime->timeValueLowWord,
++ &auxTime->timeValueHighWord);
++ IOH_DEBUG("ioh_1588_aux_time_poll:Auxiliary Slave Snapshot \
++ low=%lx,high=%lx\n", auxTime->timeValueLowWord, \
++ auxTime->timeValueHighWord);
++
++ *pollFlag = TRUE;
++
++ /* Clear the snapshot availability condition */
++ IOH_DEBUG
++ ("ioh_1588_aux_time_poll:invoking ioh_1588_amms_evt_clear\n");
++ ioh_1588_asms_evt_clear();
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_reset(void)
++ *
++ * @brief Resets the IEEE 1588 hardware assist block
++ *
++ * @remarks Resets the IEEE 1588 hardware assist block. The
++ * main steps followed in this function are:
++ * - Set the reset bit of Time Sync Control register
++ * - Clear the reset bit of Time Sync Control register
++ * -Note: For A0/A1 sample, test mode setting is enabled for
++ * the 64 bit System Time Register. This is a work around for
++ * the non continuous value in the 64 bit System Time Register
++ * consisting of High(32bit) / Low(32bit)
++ *
++ *
++ * @param None
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation is successful
++ */
++enum ioh_status ioh_1588_reset(void)
++{
++ /* Reset Hardware Assist */
++ IOH_DEBUG("ioh_1588_reset:invoking ioh_1588_block_reset\n");
++ ioh_1588_block_reset();
++
++ /* Clear Stats */
++ ioh_1588_stats.rxMsgs = ioh_1588_stats.txMsgs = 0;
++
++ /* Unregister any Callback Routines */
++ IOH_DEBUG("ioh_1588_reset:unregistering callbacks\n");
++ ioh_pps_cbptr = (ioh1588PulsePerSecondCallback) NULL;
++ ioh_am_cbptr = (ioh1588AuxTimeCallback) NULL;
++ ioh_as_cbptr = (ioh1588AuxTimeCallback) NULL;
++ ioh_tt_cbptr = (ioh1588TargetTimeCallback) NULL;
++
++#ifdef IOH_IEEE1588_A0_A1_SAMPLE_BUG
++ /*enable all 32 bits in system time registers */
++ ioh_1588_set_system_time_count();
++#endif
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_chnl_reset(enum ioh1588PTPPort ptpPort)
++ *
++ * @brief Resets the IEEE 1588 channel by resetting the hardware block
++ *
++ * @remarks This API also sets the reset bit in the IEEE1588 to fully
++ * resets the block. The main steps followed in this function
++ * are:
++ * - Return IOH_1588_INVALIDPARAM if ptpPort passed is not valid
++ * - Perform a block level reset by invoking ioh_1588_reset
++ *
++ *
++ * @param ptpPort [IN] The PTP port that is to be reset
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_chnl_reset(enum ioh1588PTPPort ptpPort)
++{
++ IOH_DEBUG("ioh_1588_chnl_reset:invoking ioh_1588_reset\n");
++ return ioh_1588_reset();
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_stats_get(struct ioh1588Stats *stats)
++ *
++ * @brief Returns the ioh1588 Statistics
++ *
++ * @remarks This API will return the statistics of the snapshots captured
++ * for
++ * receive and transmit of messages. The main steps followed in
++ * this
++ * function are:
++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL
++ * - Return the counter values stored for Rx and Tx messages
++ *
++ *
++ * @param stats [OUT] Buffer for returning the statistics
++ * counter values
++ *
++ *
++ * @note These counters are updated only when the client application
++ * polls for
++ * the time stamps or interrupt are enabled.
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation is successful
++ * @li IOH_1588_INVALIDPARAM - NULL parameter passed
++ */
++
++enum ioh_status ioh_1588_stats_get(struct ioh1588Stats *stats)
++{
++ /* Verify the parameter */
++ if ((struct ioh1588Stats *) NULL == stats) {
++ IOH_DEBUG("ioh_1588_stats_get:invalid param \
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Return the statistics */
++ stats->rxMsgs = ioh_1588_stats.rxMsgs;
++ stats->txMsgs = ioh_1588_stats.txMsgs;
++ IOH_DEBUG("ioh_1588_stats_get:stats-txMsg=%lx,rxMsg=%lx\n",
++ stats->txMsgs, stats->rxMsgs);
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn void ioh_1588_stats_reset(void)
++ *
++ * @brief Resets the statistics counters
++ *
++ * @remarks This API will reset the statistics counters maintained by the
++ * driver
++ *
++ * @param None
++ * @retval None
++ */
++void ioh_1588_stats_reset(void)
++{
++ /* Clear the statistics */
++ IOH_DEBUG("ioh_1588_stats_reset:clearing stats\n");
++ ioh_1588_stats.rxMsgs = ioh_1588_stats.txMsgs = 0;
++
++ return;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn void ioh_1588_save_state(void)
++ *
++ * @brief Save the state of all registers
++ *
++ * @remarks Save the content of all registers of IEEE1588 module
++ *
++ * @param None.
++ *
++ * @retval None
++ */
++void ioh_1588_save_state(void)
++{
++ int i;
++ unsigned long val;
++
++ /* Time stamp control register */
++ ioh_1588_regs.ts_control =
++ (ioh_1588_ttm_imask_get() << IOH_1588_TSC_TTM_SHIFT) |
++ (ioh_1588_asms_imask_get() << IOH_1588_TSC_ASMS_SHIFT) |
++ (ioh_1588_amms_imask_get() << IOH_1588_TSC_AMMS_SHIFT) |
++ (ioh_1588_pps_imask_get() << IOH_1588_TSC_PPSM_SHIFT);
++ IOH_DEBUG("ioh_1588_save_state:TS_CONTROL reg=%lx\n",
++ ioh_1588_regs.ts_control);
++
++ /*
++ * Time stamp event register; clear on write,
++ * so no point in reading and then saving;
++ * Will be cleared on restore to start in a clean slate
++ */
++ ioh_1588_regs.ts_event = IOH_1588_TSE_TTIPEND | IOH_1588_TSE_SNS |
++ IOH_1588_TSE_SNM | IOH_1588_TSE_PPS;
++ IOH_DEBUG("ioh_1588_save_state:TS_EVENT reg=%lx\n",
++ ioh_1588_regs.ts_event);
++
++ /* Addend register */
++ ioh_1588_addend_get(&ioh_1588_regs.ts_addend);
++ IOH_DEBUG("ioh_1588_save_state:TS_ADDEND reg=%lx\n",
++ ioh_1588_regs.ts_addend);
++
++ /* PPS comapre register */
++ ioh_1588_pps_get(&ioh_1588_regs.ts_compare);
++ IOH_DEBUG("ioh_1588_save_state:TS_COMPARE reg=%lx\n",
++ ioh_1588_regs.ts_compare);
++
++ /* System time Low and Hi registers */
++ ioh_1588_sys_snap_get(&ioh_1588_regs.ts_syslo, &ioh_1588_regs.ts_syshi);
++ IOH_DEBUG("ioh_1588_save_state:sys time reg-low =%lx,high=%lx\n",
++ ioh_1588_regs.ts_syslo, ioh_1588_regs.ts_syshi);
++
++ /* Target time Low and Hi registers */
++ ioh_1588_tgt_snap_get(&ioh_1588_regs.ts_tgtlo, &ioh_1588_regs.ts_tgthi);
++ IOH_DEBUG("ioh_1588_save_state:target time reg-low =%lx,high=%lx\n",
++ ioh_1588_regs.ts_tgtlo, ioh_1588_regs.ts_tgthi);
++
++#if 0
++ /*
++ * Below registers are read only, so no point in reading/storing, since
++ * we can't restore them
++ */
++ /* Slave mode snapshot Low and Hi registers */
++ ioh_1588_aux_slave_snap_get(&ioh_1588_regs.ts_asmslo,
++ &ioh_1588_regs.ts_asmshi);
++
++ /* Master mode snapshot Low and Hi registers */
++ ioh_1588_aux_master_snap_get(&ioh_1588_regs.ts_ammslo,
++ &ioh_1588_regs.ts_ammshi);
++#endif
++ ioh_1588_regs.ts_cc =
++ (ioh_1588_master_mode_get() << IOH_1588_CC_MM_SHIFT) |
++ (ioh_1588_timestamp_all_get() << IOH_1588_CC_TA_SHIFT) |
++ (ioh_1588_op_mode_get() << IOH_1588_CC_MODE_SHIFT) |
++ (ioh_1588_version_get() << IOH_1588_CC_VERSION_SHIFT);
++ IOH_DEBUG("ioh_1588_save_state:TS_CC reg=%lx\n", ioh_1588_regs.ts_cc);
++
++ /* Channel event register, not saved - will be cleared on restore */
++ ioh_1588_regs.ts_ce = IOH_1588_CE_TXS | IOH_1588_CE_RXS;
++
++#if 0
++ /*
++ * Below registers are read only, so no point in reading/storing, since
++ * we can't restore them
++ */
++ ioh_1588_rx_snap_get(&ioh_1588_regs.ts_xslo, &ioh_1588_regs.ts_xshi);
++ ioh_1588_tx_snap_get(&ioh_1588_regs.ts_rslo, &ioh_1588_regs.ts_rshi);
++ ioh_1588_uuid_seqid_get(&ioh_1588_regs.ts_uuidlo,
++ &ioh_1588_regs.ts_uuidhi);
++
++ /* CAN */
++ ioh_1588_can_snap_get(&ioh_1588_regs.ts_cxslo, &ioh_1588_regs.ts_cxshi);
++#endif
++
++ /* CAN Channel event register, not saved - will be cleared on restore */
++ ioh_1588_regs.ts_cce = IOH_1588_CE_OVR | IOH_1588_CE_VAL;
++
++ /* Ethernet CAN selector register */
++ ioh_1588_regs.ts_sel =
++ (ioh_1588_eth_enable_get() << IOH_1588_ECS_ETH_SHIFT) |
++ (ioh_1588_can_enable_get() << IOH_1588_ECS_CAN_SHIFT);
++ IOH_DEBUG("ioh_1588_save_state:TS_SEL reg=%lx\n", ioh_1588_regs.ts_sel);
++
++ /* Station Address registers */
++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) {
++ ioh_1588_station_get(i, &val);
++ ioh_1588_regs.ts_sti[i] = val & 0xff;
++ IOH_DEBUG("ioh_1588_save_state:TS_ST[%d] reg=%d\n", i,
++ ioh_1588_regs.ts_sti[i]);
++ }
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn void ioh_1588_restore_state(void)
++ *
++ * @brief Restore the state of all registers
++ *
++ * @remarks Restores the content of all registers of IEEE1588 module.
++ * Note: For A0/A1 sample, test mode setting is enabled for
++ * the 64 bit System Time Register. This is a work around for
++ * the non continuous value in the 64 bit System Time
++ * Register
++ * consisting of High(32bit) / Low(32bit)
++ *
++ * @param None
++ * @retval None
++ */
++void ioh_1588_restore_state(void)
++{
++ int i;
++
++ /* Time stamp control register */
++ if (ioh_1588_regs.ts_control & IOH_1588_TSC_TTM_MASK) {
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_ttm_imask_set\n");
++ ioh_1588_ttm_imask_set();
++ }
++ if (ioh_1588_regs.ts_control & IOH_1588_TSC_ASMS_MASK) {
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_asms_imask_set\n");
++ ioh_1588_asms_imask_set();
++ }
++ if (ioh_1588_regs.ts_control & IOH_1588_TSC_AMMS_MASK) {
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_amms_imask_set\n");
++ ioh_1588_amms_imask_set();
++ }
++ if (ioh_1588_regs.ts_control & IOH_1588_TSC_PPSM_MASK) {
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_pps_imask_set\n");
++ ioh_1588_pps_imask_set();
++ }
++
++ /* Time stamp event register; clear all events */
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_ttm_evt_clear\n");
++ ioh_1588_ttm_evt_clear();
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_asms_evt_clear\n");
++ ioh_1588_asms_evt_clear();
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_amms_evt_clear\n");
++ ioh_1588_amms_evt_clear();
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_pps_evt_clear\n");
++ ioh_1588_pps_evt_clear();
++
++#ifdef IOH_IEEE1588_A0_A1_SAMPLE_BUG
++ /*enable all 32 bits in system time registers */
++ ioh_1588_set_system_time_count();
++#endif
++
++ /* Addend register */
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_addend_set\n");
++ ioh_1588_addend_set(ioh_1588_regs.ts_addend);
++
++ /* PPS comapre register */
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_pps_set\n");
++ ioh_1588_pps_set(ioh_1588_regs.ts_compare);
++
++ /* System time Low and Hi registers */
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_sys_snap_set\n");
++ ioh_1588_sys_snap_set(ioh_1588_regs.ts_syslo, ioh_1588_regs.ts_syshi);
++
++ /* Target time Low and Hi registers */
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_tgt_snap_set\n");
++ ioh_1588_tgt_snap_set(ioh_1588_regs.ts_tgtlo, ioh_1588_regs.ts_tgthi);
++
++ /* Ethernet Channel Control register */
++ if (ioh_1588_regs.ts_cc & IOH_1588_CC_MM) {
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_master_mode_set\
++ with TRUE as parameter\n");
++ ioh_1588_master_mode_set(TRUE);
++ }
++ if (ioh_1588_regs.ts_cc & IOH_1588_CC_TA) {
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_timestamp_all_set\
++ with TRUE as parameter\n");
++ ioh_1588_timestamp_all_set(TRUE);
++ }
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_op_mode_set\n");
++ ioh_1588_op_mode_set((ioh_1588_regs.ts_cc & IOH_1588_CC_MODE_MASK) >>
++ IOH_1588_CC_MODE_SHIFT);
++ if (ioh_1588_regs.ts_cc & IOH_1588_CC_VERSION) {
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_version_set\
++ with IOH_1588PTP_VERSION_1 as parameter\n");
++ ioh_1588_version_set(IOH_1588PTP_VERSION_1);
++ }
++
++ /* Channel event register, cleared on restore */
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_rx_snap_evt_clear\n");
++ ioh_1588_rx_snap_evt_clear();
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_tx_snap_evt_clear\n");
++ ioh_1588_tx_snap_evt_clear();
++
++ /* CAN Channel event register, cleared on restore */
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_tx_snap_ovr_clear\n");
++ ioh_1588_can_snap_ovr_clear();
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_tx_snap_valid_clear\n");
++ ioh_1588_can_snap_valid_clear();
++
++ /* Ethernet CAN selector register */
++ if (ioh_1588_regs.ts_sel & IOH_1588_ECS_ETH) {
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_eth_enable_set\n");
++ ioh_1588_eth_enable_set();
++ }
++ if (ioh_1588_regs.ts_sel & IOH_1588_ECS_CAN) {
++ IOH_DEBUG
++ ("ioh_1588_restore_state:invoking ioh_1588_can_enable_set\n");
++ ioh_1588_can_enable_set();
++ }
++
++ /* Station Address registers */
++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) {
++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_station_set\
++ for station=%d\n", i);
++ ioh_1588_station_set(i, ioh_1588_regs.ts_sti[i]);
++ }
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn void ioh_1588_show(void)
++ *
++ * @brief Display the dump of IEEE 1588 registers
++ *
++ * @remarks This API will dump the contents of configuration, event and
++ * snapshot
++ * registers of the IEEE1588 module
++ *
++ * @param None.
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS
++ */
++enum ioh_status ioh_1588_show(void)
++{
++ int i;
++ unsigned long flag = FALSE;
++ unsigned long reg_low = 0;
++ unsigned long reg_hi = 0;
++ unsigned int seq_id = 0;
++ unsigned long uuid_low = 0;
++ unsigned long uuid_hi = 0;
++
++ /*dump all register as such */
++ IOH_DEBUG("TS Control Register offset = %x,content = %x\n",
++ IOH_1588_TSC_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_TSC_OFFSET));
++ IOH_DEBUG("TS Event Register offset = %x,content = %x\n",
++ IOH_1588_TSE_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_TSE_OFFSET));
++ IOH_DEBUG("TS Addend Register offset = %x,content = %x\n",
++ IOH_1588_ADD_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_ADD_OFFSET));
++ IOH_DEBUG("TS Accumulator Register offset = %x,content = %x\n",
++ IOH_1588_ACC_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_ACC_OFFSET));
++ IOH_DEBUG("TS Test Register offset = %x,content = %x\n",
++ IOH_1588_TST_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_TST_OFFSET));
++ IOH_DEBUG("TS PPS Compare Register offset = %x,content = %x\n",
++ IOH_1588_PPS_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_PPS_OFFSET));
++ IOH_DEBUG("TS System Time Low Register offset = %x,content = %x\n",
++ IOH_1588_STL_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_STL_OFFSET));
++ IOH_DEBUG("TS System Time High Register offset = %x,content = %x\n",
++ IOH_1588_STH_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_STH_OFFSET));
++ IOH_DEBUG("TS Target Time Low Register offset = %x,content = %x\n",
++ IOH_1588_TTL_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_TTL_OFFSET));
++ IOH_DEBUG("TS Target Time High Register offset = %x,content = %x\n",
++ IOH_1588_TTH_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_TTH_OFFSET));
++ IOH_DEBUG
++ ("TS Aux Slave Mode Snapshot Low Register offset = %x,content = %x\n",
++ IOH_1588_ASSL_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_ASSL_OFFSET));
++ IOH_DEBUG
++ ("TS Aux Slave Mode Snapshot High Register offset = %x,content = %x\n",
++ IOH_1588_ASSH_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_ASSH_OFFSET));
++ IOH_DEBUG
++ ("TS Aux Master Mode Snapshot Low Register offset = %x,content = %x\n",
++ IOH_1588_AMSL_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_AMSL_OFFSET));
++ IOH_DEBUG
++ ("TS Aux Master Mode Snapshot High Register offset = %x,content = %x\n",
++ IOH_1588_AMSH_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_AMSH_OFFSET));
++ IOH_DEBUG("TS Channel Control Register offset = %x,content = %x\n",
++ IOH_1588_CC_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_CC_OFFSET));
++ IOH_DEBUG("TS Channel Event Register offset = %x,content = %x\n",
++ IOH_1588_CE_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_CE_OFFSET));
++ IOH_DEBUG("TS Tx Snapshot High Register offset = %x,content = %x\n",
++ IOH_1588_XSH_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_XSH_OFFSET));
++ IOH_DEBUG("TS Tx Snapshot Low Register offset = %x,content = %x\n",
++ IOH_1588_XSL_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_XSL_OFFSET));
++ IOH_DEBUG("TS Rx Snapshot Low Register offset = %x,content = %x\n",
++ IOH_1588_RSL_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_RSL_OFFSET));
++ IOH_DEBUG("TS Rx Snapshot High Register offset = %x,content = %x\n",
++ IOH_1588_RSH_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_RSH_OFFSET));
++ IOH_DEBUG("TS Source UUID Low Register offset = %x,content = %x\n",
++ IOH_1588_UID_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_UID_OFFSET));
++ IOH_DEBUG
++ ("TS Source UUID High/SequenceID Register offset = %x,content = %x\n",
++ IOH_1588_SID_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_SID_OFFSET));
++ IOH_DEBUG("TS CAN Channel Status Register offset = %x,content = %x\n",
++ IOH_1588_CCE_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_CCE_OFFSET));
++ IOH_DEBUG("TS CAN Snapshot Low Register offset = %x,content = %x\n",
++ IOH_1588_CXSL_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_CXSL_OFFSET));
++ IOH_DEBUG("TS CAN Snapshot High Register offset = %x,content = %x\n",
++ IOH_1588_CXSH_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_CXSH_OFFSET));
++ IOH_DEBUG("TS Ethernet/CAN Selecti Register offset = %x,content = %x\n",
++ IOH_1588_ECS_OFFSET,
++ IOH_READ32(ioh_1588_base + IOH_1588_ECS_OFFSET));
++ /* Station Address registers */
++ IOH_DEBUG("TS Station Address [1-6]");
++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) {
++ ioh_1588_station_get(i, &reg_low);
++ IOH_DEBUG(":%02lx", reg_low);
++ }
++ IOH_DEBUG("\n");
++
++ /* Target time reached interrupt mask */
++ flag = ioh_1588_ttm_imask_get();
++ IOH_LOG(KERN_ERR, "Target Time Interrupt Mask: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Auxiliary Slave Mode Snapshot interrupt mask */
++ flag = ioh_1588_asms_imask_get();
++ IOH_LOG(KERN_ERR, "ASMS Interrupt Mask: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Auxiliary Master Mode Snapshot interrupt mask */
++ flag = ioh_1588_amms_imask_get();
++ IOH_LOG(KERN_ERR, "AMMS Interrupt Mask: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Pulse per second interrupt mask */
++ flag = ioh_1588_pps_imask_get();
++ IOH_LOG(KERN_ERR, "PPS Interrupt Mask: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* TS_Event Register */
++ /* Target time interrupt event */
++ flag = ioh_1588_ttm_evt_get();
++ IOH_LOG(KERN_ERR, "Target Time Interrupt Pending: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Auxiliary Slave Mode Snapshot event */
++ flag = ioh_1588_asms_evt_get();
++ IOH_LOG(KERN_ERR, "ASMS Snapshot Event: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Auxiliary Master Mode Snapshot event */
++ flag = ioh_1588_amms_evt_get();
++ IOH_LOG(KERN_ERR, "AMMS Snapshot Event: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* PPS Match event */
++ flag = ioh_1588_pps_evt_get();
++ IOH_LOG(KERN_ERR, "PPS Match Event: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Addend Register */
++ reg_low = 0;
++ ioh_1588_addend_get(&reg_low);
++ IOH_LOG(KERN_ERR, "Frequency Scaling Value: %lx\n", reg_low);
++
++ /* PPS Comapre Register */
++ reg_low = 0;
++ ioh_1588_pps_get(&reg_low);
++ IOH_LOG(KERN_ERR, "PPS Compare Register Value: %lx\n", reg_low);
++
++ /* System Time registers */
++ reg_low = reg_hi = 0;
++ ioh_1588_sys_snap_get(&reg_low, &reg_hi);
++ IOH_LOG(KERN_ERR, "System Time (Hi:Low): %lx : %lx\n", reg_hi, reg_low);
++
++ /* Target Time registers */
++ reg_low = reg_hi = 0;
++ ioh_1588_tgt_snap_get(&reg_low, &reg_hi);
++ IOH_LOG(KERN_ERR, "Target Time (Hi:Low): %lx : %lx\n", reg_hi, reg_low);
++
++ /* Auxiliary Slave Mode Snapshot registers */
++ reg_low = reg_hi = 0;
++ ioh_1588_aux_slave_snap_get(&reg_low, &reg_hi);
++ IOH_LOG(KERN_ERR,
++ "Auxiliary Slave Mode Snapshot (Hi:Low) : %lx : %lx\n", reg_hi,
++ reg_low);
++
++ /* Auxiliary Master Mode Snapshot registers */
++ reg_low = reg_hi = 0;
++ ioh_1588_aux_master_snap_get(&reg_low, &reg_hi);
++ IOH_LOG(KERN_ERR,
++ "Auxiliary Master Mode Snapshot (Hi:Low): %lx : %lx\n", reg_hi,
++ reg_low);
++
++ /* Ethernet port */
++ IOH_LOG(KERN_ERR, "\nPTP Eth Port\n");
++
++ /* Master Mode */
++ flag = ioh_1588_master_mode_get();
++ IOH_LOG(KERN_ERR, "Master Mode: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Timestamp All PTP messages */
++ flag = ioh_1588_timestamp_all_get();
++ IOH_LOG(KERN_ERR, "Timestamp All Messages: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Version */
++ flag = ioh_1588_version_get();
++ IOH_LOG(KERN_ERR, "Version support: %s\n",
++ ((TRUE == flag) ? "v1 and v2" : "v1 only"));
++
++ /* Receive Snapshot Locked */
++ flag = ioh_1588_rx_snap_evt();
++ IOH_LOG(KERN_ERR, "Receive Snapshot Locked: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Transmit Snapshot Locked */
++ flag = ioh_1588_tx_snap_evt();
++ IOH_LOG(KERN_ERR, "Transmit Snapshot Locked: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Receive Snapshot registers */
++ reg_low = reg_hi = 0;
++ ioh_1588_rx_snap_get(&reg_low, &reg_hi);
++ IOH_LOG(KERN_ERR, "Receive Snapshot (Hi:Low): %lx : %lx\n", reg_hi,
++ reg_low);
++
++ /* Transmit Snapshot registers */
++ reg_low = reg_hi = 0;
++ ioh_1588_tx_snap_get(&reg_low, &reg_hi);
++ IOH_LOG(KERN_ERR, "Transmit Snapshot (Hi:Low): %lx : %lx\n", reg_hi,
++ reg_low);
++
++ /* UUID and Seqquence Id */
++ ioh_1588_uuid_seqid_get(&uuid_low, &uuid_hi, &seq_id);
++ IOH_LOG(KERN_ERR, "UUID (Hi:Lo): %lx : %lx\n", uuid_hi, uuid_low);
++ IOH_LOG(KERN_ERR, "Sequence id: %x\n", seq_id);
++
++ /* CAN port */
++ IOH_LOG(KERN_ERR, "\nPTP CAN Port:\n");
++
++ /* Snapshot Valid */
++ flag = ioh_1588_can_snap_valid();
++ IOH_LOG(KERN_ERR, "Snapshot Valid : %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Snapshot Overrun */
++ flag = ioh_1588_can_snap_ovr();
++ IOH_LOG(KERN_ERR, "Snapshot Overrun: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* CAN Snapshot registers */
++ reg_low = reg_hi = 0;
++ ioh_1588_can_snap_get(&reg_low, &reg_hi);
++ IOH_LOG(KERN_ERR, "CAN Snapshot (Hi:Low): %lx : %lx\n", reg_hi,
++ reg_low);
++
++ /* Ethernet Selector */
++ flag = ioh_1588_eth_enable_get();
++ IOH_LOG(KERN_ERR, "\nEthernet Enable: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* CAN Selector */
++ flag = ioh_1588_can_enable_get();
++ IOH_LOG(KERN_ERR, "CAN Enable: %s\n",
++ ((TRUE == flag) ? "Set" : "Clear"));
++
++ /* Station Address Registers */
++ IOH_LOG(KERN_ERR, "Station Address [1-6]");
++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) {
++ ioh_1588_station_get(i, &reg_low);
++ IOH_LOG(KERN_ERR, ":%02lx", reg_low);
++ }
++ IOH_LOG(KERN_ERR, "\n");
++
++ /* Statistics */
++ IOH_LOG(KERN_ERR,
++ "Receive Snapshot Count: %lu\nTransmit Snapshot Count: %lu\n",
++ ioh_1588_stats.rxMsgs, ioh_1588_stats.txMsgs);
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_can_poll (
++ * enum ioh1588PTPPort ptpPort,
++ * struct ioh1588TimeValue *ptpTimeStamp)
++ *
++ * @brief Polls the IEEE 1588 message time stamp detect status on a given
++ * CAN PTP Port.
++ *
++ * @remarks This API polls for the availability of a time stamp on a CAN
++ * port.
++ *
++ * @param ptpPort [IN] PTP port to poll
++ * @param ptpTimeStamp [OUT] Buffer to store the snapshot captured
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed
++ * @li IOH_1588_NOTIMESTAMP - No time stamp available
++ */
++enum ioh_status
++ioh_1588_ptp_can_poll(enum ioh1588PTPPort ptpPort, \
++ struct ioh1588TimeValue *ptpTimeStamp)
++{
++ unsigned long valid = FALSE;
++ unsigned long overrun = FALSE;
++
++ /* Verify the parameters for proper values */
++ if ((ptpPort != IOH_1588_CAN_0_1588PTP_PORT) ||
++ ((struct ioh1588TimeValue *) NULL == ptpTimeStamp)) {
++ IOH_DEBUG("ioh_1588_ptp_can_poll:invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Check whether a new timestamp available? */
++ IOH_DEBUG("ioh_1588_ptp_can_poll:invoking ioh_1588_can_snap_valid\n");
++ valid = ioh_1588_can_snap_valid();
++
++ /* there is not a valid timestamp */
++ if (TRUE != valid) {
++ IOH_DEBUG("ioh_1588_ptp_can_poll:no valid timestamp\
++ returning IOH_1588_NOTIMESTAMP\n");
++ return IOH_1588_NOTIMESTAMP;
++ }
++
++ /* check overrun bit before retreiving timestamp */
++ IOH_DEBUG("ioh_1588_ptp_can_poll:invoking ioh_1588_can_snap_ovr\n");
++ overrun = ioh_1588_can_snap_ovr();
++
++ /* if the timestamp has been overwritten */
++ if (TRUE == overrun) {
++ IOH_DEBUG("ioh_1588_ptp_can_poll:overrun occured\n");
++ /* reset valid and overrun bits */
++ IOH_DEBUG
++ ("ioh_1588_ptp_can_poll:invoking \
++ ioh_1588_can_snap_valid_clear\n");
++ ioh_1588_can_snap_valid_clear();
++ IOH_DEBUG
++ ("ioh_1588_ptp_can_poll:invoking \
++ ioh_1588_can_snap_ovr_clear\n");
++ ioh_1588_can_snap_ovr_clear();
++
++ /* return no valid timestamp available */
++ ptpTimeStamp->timeValueLowWord = 0;
++ ptpTimeStamp->timeValueHighWord = 0;
++
++ IOH_DEBUG
++ ("ioh_1588_ptp_can_poll:returning IOH_1588_NOTIMESTAMP\n");
++ return IOH_1588_NOTIMESTAMP;
++ }
++
++ /* Fetch the receive timestamp */
++ ioh_1588_can_snap_get(&ptpTimeStamp->timeValueLowWord,
++ &ptpTimeStamp->timeValueHighWord);
++ IOH_DEBUG("ioh_1588_ptp_can_poll:timestamp-low=%lx,high=%lx\n",
++ ptpTimeStamp->timeValueLowWord,
++ ptpTimeStamp->timeValueHighWord);
++
++ /* check overrun bit again to ensure timestamp is valid */
++ overrun = ioh_1588_can_snap_ovr();
++
++ /* if the timestamp has been overwritten */
++ if (TRUE == overrun) {
++ IOH_DEBUG("ioh_1588_ptp_can_poll:overrun occured\n");
++ /* reset valid and overrun bits */
++ IOH_DEBUG
++ ("ioh_1588_ptp_can_poll:invoking \
++ ioh_1588_can_snap_valid_clear\n");
++ ioh_1588_can_snap_valid_clear();
++ IOH_DEBUG
++ ("ioh_1588_ptp_can_poll:invoking \
++ ioh_1588_can_snap_ovr_clear\n");
++ ioh_1588_can_snap_ovr_clear();
++
++ /* return no valid timestamp available */
++ ptpTimeStamp->timeValueLowWord = 0;
++ ptpTimeStamp->timeValueHighWord = 0;
++
++ IOH_DEBUG
++ ("ioh_1588_ptp_can_poll:returning IOH_1588_NOTIMESTAMP\n");
++ return IOH_1588_NOTIMESTAMP;
++ }
++
++ /* reset valid bit */
++ IOH_DEBUG
++ ("ioh_1588_ptp_can_poll:invoking ioh_1588_can_snap_valid_clear\n");
++ ioh_1588_can_snap_valid_clear();
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_handler(void)
++ *
++ * @brief Interrupt handler for the IEEE 1588 module
++ *
++ * @remarks Interrupt handler for the IEEE 1588 module
++ * The Interrupts are handled in the following order
++ * - 1 - Target Time Reached/Hit Condition
++ * - 2 - Auxiliary Master Timestamp
++ * - 3 - Auxiliary Slave Timestamp
++ * - 4 - pulse per second
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_handler(void)
++{
++ struct ioh1588TimeValue tgt_time = { 0, 0 };
++ struct ioh1588TimeValue aux_time = { 0, 0 };
++ unsigned long pps;
++
++ /* If valid callbacks are available process each interrupt */
++
++ /* Handle Target Time Reached or Exceeded Interrupt */
++ if ((NULL != ioh_tt_cbptr) && (TRUE == ioh_1588_ttm_evt_get())) {
++ IOH_DEBUG
++ ("ioh_1588_handler:Target Time Reached or Exceeded \
++ Interrupt\n");
++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_ttm_imask_clear\
++ to disable interrupts\n");
++ /* Disable interrupt */
++ ioh_1588_ttm_imask_clear();
++
++ /* Target Time registers contents */
++ ioh_1588_tgt_snap_get(&tgt_time.timeValueLowWord,
++ &tgt_time.timeValueHighWord);
++ IOH_DEBUG("ioh_1588_handler:target time-low=%lx,high=%lx\n",
++ tgt_time.timeValueLowWord,
++ tgt_time.timeValueHighWord);
++
++ IOH_DEBUG("ioh_1588_handler:invoking callback\n");
++ /* Invoke client callback */
++ (*ioh_tt_cbptr) (tgt_time);
++
++ /* Clear the target time reached condition (ttipend bit) */
++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_ttm_evt_clear\n");
++ ioh_1588_ttm_evt_clear();
++ }
++
++ /* Handle Auxiliary Master Mode Snapshot Interrupt */
++ if ((NULL != ioh_am_cbptr) && (TRUE == ioh_1588_amms_evt_get())) {
++ IOH_DEBUG
++ ("ioh_1588_handler:Auxiliary Master Mode Snapshot Interrupt\n");
++ /* Disable interrupt */
++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_amms_imask_clear\
++ to disable interrupts\n");
++ ioh_1588_amms_imask_clear();
++
++ /* Fetch Auxiliary Master Mode Snapshot */
++ ioh_1588_aux_master_snap_get(&aux_time.timeValueLowWord,
++ &aux_time.timeValueHighWord);
++ IOH_DEBUG
++ ("ioh_1588_handler:Auxiliary Master Mode Snapshot-low=%lx,\
++ high=%lx\n",
++ aux_time.timeValueLowWord, aux_time.timeValueHighWord);
++
++ IOH_DEBUG("ioh_1588_handler:invoking callback\n");
++ /* Return Auxiliary Master Mode Snapshot */
++ (*ioh_am_cbptr) (IOH_1588_AUXMODE_MASTER, aux_time);
++
++ /* Clear the snapshot availability condition */
++ IOH_DEBUG
++ ("ioh_1588_handler:invoking ioh_1588_amms_evt_clear\n");
++ ioh_1588_amms_evt_clear();
++ }
++
++ /* Handle Auxiliary Slave Mode Snapshot Interrupt */
++ if ((NULL != ioh_as_cbptr) && (TRUE == ioh_1588_asms_evt_get())) {
++ IOH_DEBUG
++ ("ioh_1588_handler:Auxiliary Slave Mode Snapshot Interrupt\n");
++ /* Disable interrupt */
++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_asms_imask_clear\
++ to disable interrupts\n");
++ ioh_1588_asms_imask_clear();
++
++ /* Fetch Auxiliary Slave Mode Snapshot */
++ ioh_1588_aux_slave_snap_get(&aux_time.timeValueLowWord,
++ &aux_time.timeValueHighWord);
++ IOH_DEBUG
++ ("ioh_1588_handler:Auxiliary Master Mode Snapshot-low=%lx,\
++ high=%lx\n",
++ aux_time.timeValueLowWord, aux_time.timeValueHighWord);
++
++ /* Return Auxiliary Slave Mode Snapshot */
++ IOH_DEBUG("ioh_1588_handler:invoking callback\n");
++ (*ioh_as_cbptr) (IOH_1588_AUXMODE_SLAVE, aux_time);
++
++ /* Clear the snapshot availability condition */
++ IOH_DEBUG
++ ("ioh_1588_handler:invoking ioh_1588_asms_evt_clear\n");
++ ioh_1588_asms_evt_clear();
++ }
++
++ /* Handle Pulse Per Second Interrupt */
++ if ((NULL != ioh_pps_cbptr) && (TRUE == ioh_1588_pps_evt_get())) {
++ IOH_DEBUG("ioh_1588_handler:Pulse Per Second Interrupt\n");
++ /* Disable interrupt */
++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_pps_imask_clear\
++ to disable interrupts\n");
++ ioh_1588_pps_imask_clear();
++
++ /* Fetch PPS compare register */
++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_pps_get\n");
++ ioh_1588_pps_get(&pps);
++
++ /* Invoke the call back */
++ IOH_DEBUG("ioh_1588_handler:invoking callback\n");
++ (*ioh_pps_cbptr) (pps);
++
++ /* Clear the snapshot availability condition */
++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_pps_evt_clear\n");
++ ioh_1588_pps_evt_clear();
++
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_version_get(
++ * enum ioh1588PTPPort ptpPort, enum ioh1588PTPVersion *ptpVersion)
++ *
++ * @brief Retrieves IEEE 1588 PTP version supported on the given PTP port.
++ *
++ * @remarks This API retrieves IEEE 1588 PTP version supported on given PTP
++ * port.
++ * The main steps followed in this function are:
++ * - Return IOH_1588_INVALIDPARAM if ptpPort passed is not valid or
++ * ptpVersion passed is NULL
++ * - Ensure that the module is initialized and the port is valid
++ * - Return the PTP version that is supported from the
++ * TS_Channel_Control register, bit 31
++ *
++ *
++ * @param ptpPort [IN] PTP port
++ * @param ptpVersion [OUT] Version supported on PTP port
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation is successful
++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed
++ */
++enum ioh_status
++ioh_1588_ptp_version_get(enum ioh1588PTPPort ptpPort, \
++ enum ioh1588PTPVersion *ptpVersion)
++{
++ /* Verify the parameters for proper values */
++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) || (ptpVersion == NULL)) {
++ IOH_DEBUG("ioh_1588_ptp_version_get:invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ IOH_DEBUG("ioh_1588_ptp_version_get:invoking ioh_1588_version_get\n");
++ *ptpVersion = ioh_1588_version_get();
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_version_set(
++ * enum ioh1588PTPPort ptpPort,
++ * enum ioh1588PTPVersion ptpVersion)
++ *
++ * @brief Configures IEEE 1588 PTP version to be used on given PTP port.
++ *
++ * @remarks This API set the IEEE 1588 PTP version to be used on given PTP
++ * port.
++ * The main steps followed in this function are:
++ * - Validate parameter
++ * - Ensure that the module is initialized and the version
++ * requested is valid
++ * - Set the version in TS_Channel_Control register, bit 31
++ *
++ *
++ * @param ptpPort [IN] PTP port
++ * @param ptpVersion [IN] Version to be supported on PTP port
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation is successful
++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed
++ */
++enum ioh_status
++ioh_1588_ptp_version_set(enum ioh1588PTPPort ptpPort, \
++ enum ioh1588PTPVersion ptpVersion)
++{
++ /* Verify the parameters for proper values */
++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) ||
++ ((ptpVersion != IOH_1588PTP_VERSION_0) &&
++ (ptpVersion != IOH_1588PTP_VERSION_1))) {
++ IOH_DEBUG("ioh_1588_ptp_version_set:invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ IOH_DEBUG("ioh_1588_ptp_version_get:invoking ioh_1588_version_set\n");
++ ioh_1588_version_set(ptpVersion);
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_operation_mode_set(
++ * enum ioh1588PTPPort ptpPort,
++ * enum ioh1588PTPOperationMode ptpMode)
++ *
++ * @brief Configure the IEEE 1588 PTP operation mode of given PTP port.
++ *
++ * @remarks This API will set the operation mode on given PTP port.
++ * The main steps followed in this function are:
++ * - Ensure that the module is initialized and the mode requested
++ * is valid
++ * - If not valid, return status IOH_1588_INVALIDPARAM
++ * - Set the requested operation mode in TS_Channel_Control
++ * register, bits 16-20
++ *
++ *
++ * @param ptpPort [IN] PTP port to configure
++ * @param ptpMode [IN] Operation mode to be used
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed
++ */
++enum ioh_status
++ioh_1588_ptp_operation_mode_set(enum ioh1588PTPPort ptpPort,
++ enum ioh1588PTPOperationMode ptpMode)
++{
++ /* Verify the parameters for proper values */
++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) ||
++ ((ptpMode != IOH_1588PTP_OP_MODE_SYNC_DELAYREQ_MSGS) &&
++ (ptpMode != IOH_1588PTP_OP_MODE_V1_ALL_MSGS) &&
++ (ptpMode != IOH_1588PTP_OP_MODE_V1_V2_EVENT_MSGS) &&
++ (ptpMode != IOH_1588PTP_OP_MODE_V1_V2_ALL_MSGS))) {
++ IOH_DEBUG("ioh_1588_ptp_operation_mode_set:invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ IOH_DEBUG("ioh_1588_ptp_version_get:invoking ioh_1588_op_mode_set\n");
++ ioh_1588_op_mode_set(ptpMode);
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_operation_mode_get(
++ * enum ioh1588PTPPort ptpPort,
++ * enum ioh1588PTPOperationMode *ptpMode)
++ *
++ * @brief Gets the current PTP operation mode of given PTP port.
++ *
++ * @remarks This API will get the operation mode of given PTP port.
++ * The main steps followed in this function are:
++ * - Ensure that the module is initialized and the port is valid
++ * - If not valid, return status IOH_1588_INVALIDPARAM
++ * - Return the PTP operation mode that is currently in use by
++ * reading the TS_Channel_Control register, bits 16-20
++ *
++ *
++ * @param ptpPort [IN] PTP port to configure
++ * @param ptpMode [OUT] Address where PTP operation mode is
++ * returned
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Null parameter passed
++ */
++enum ioh_status
++ioh_1588_ptp_operation_mode_get(enum ioh1588PTPPort ptpPort,
++ enum ioh1588PTPOperationMode *ptpMode)
++{
++ /* Verify the parameters for proper values */
++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) || (ptpMode == NULL)) {
++ IOH_DEBUG("ioh_1588_ptp_operation_mode_get:invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ IOH_DEBUG
++ ("ioh_1588_ptp_operation_mode_get:invoking ioh_1588_op_mode_get\n");
++ *ptpMode = ioh_1588_op_mode_get();
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_pulse_per_sec_interrupt_enable(
++ * ioh1588PulsePerSecondCallback callBack)
++ *
++ * @brief Enable the Pulse Per Second match interrupt
++ *
++ * @remarks This API will enable the Pulse Per Second match interrupt.
++ * This interrupt is generated when the low word of System
++ * Time matches the value in the Pulse Per Second compare
++ * register in the IEEE hardware assist block. The main steps
++ * followed in this function are:
++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL
++ * - Modify the Time Sync Controller register to enable the
++ * interrupt
++ * - Set the callback routine
++ *
++ * @param callBack [IN] Routine to be invoked when interrupt
++ * fires
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Null parameter passed
++ */
++enum ioh_status
++ioh_1588_pulse_per_sec_interrupt_enable(ioh1588PulsePerSecondCallback callBack)
++{
++ /* Verify the parameter */
++ if ((ioh1588PulsePerSecondCallback) NULL == callBack) {
++ IOH_DEBUG
++ ("ioh_1588_pulse_per_sec_interrupt_enable:invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Register the Callback */
++ ioh_pps_cbptr = callBack;
++
++ /* Set target time interrupt mask */
++ IOH_DEBUG("ioh_1588_pulse_per_sec_interrupt_enable:invoking \
++ ioh_1588_pps_imask_set\n");
++ ioh_1588_pps_imask_set();
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_pulse_per_sec_interrupt_disable(void)
++ *
++ * @brief Disable the Pulse Per Second match interrupt
++ *
++ * @remarks This API will disable the Pulse Per Second match interrupt.
++ * This interrupt is generated when the low word of System
++ * Time matches the value in the Pulse Per Second compare
++ * register in the IEEE hardware assist block. The main
++ * steps followed in this function are:
++ * - Modify the Time Sync Controller register to disable the
++ * interrupt
++ * - Clear the callback routine
++ *
++ * @param None
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_pulse_per_sec_interrupt_disable(void)
++{
++ /* Clear pulse per second interrupt mask */
++ IOH_DEBUG("ioh_1588_pulse_per_sec_interrupt_disable:invoking \
++ ioh_1588_pps_imask_clear\n");
++ ioh_1588_pps_imask_clear();
++
++ /* Unregister the Callback */
++ ioh_pps_cbptr = (ioh1588PulsePerSecondCallback) NULL;
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_pulse_per_sec_time_set(unsigned long
++ * ppsTime)
++ *
++ * @brief Sets the Pulse Per Second match time in the IEEE 1588 hardware
++ * assist block
++ *
++ * @remarks This API will set the PPS match register with the value supplied
++ * The main steps followed in this function are:
++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL
++ * - Set the time in PPS Compare Register
++ *
++ *
++ * @param ppsTime [IN] Value to be stored in pps match register
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation is successful
++ * @li IOH_1588_INVALIDPARAM - Null parameter passed
++ */
++enum ioh_status ioh_1588_pulse_per_sec_time_set(unsigned long ppsTime)
++{
++ unsigned long old_mask = FALSE;
++
++ /* Retrieve existing pps mask value */
++ old_mask = ioh_1588_pps_imask_get();
++ IOH_DEBUG
++ ("ioh_1588_pulse_per_sec_time_set:target time interrupt mask=%lx\n",
++ old_mask);
++
++ /*
++ * Clear the pps time interrupt mask so that the interrupt will not come
++ * during the time we manipulate the registers.
++ */
++ IOH_DEBUG
++ ("ioh_1588_pulse_per_sec_time_set:invoking ioh_1588_pps_imask_clear\
++ to clear the pps interrupt mask\n");
++ ioh_1588_pps_imask_clear();
++
++ /* Update the PPS time */
++ IOH_DEBUG
++ ("ioh_1588_pulse_per_sec_time_set:invoking ioh_1588_pps_set\n");
++
++ ioh_1588_pps_set(ppsTime);
++
++ /*
++ * Let the hardware assist re-evaluate the pps reached
++ * condition based on the new pps value
++ */
++ IOH_DEBUG
++ ("ioh_1588_pulse_per_sec_time_set:invoking ioh_1588_pps_evt_clear\n");
++ ioh_1588_pps_evt_clear();
++
++ /* Restore the preserved pps interrupt mask value */
++ if (TRUE == old_mask) {
++ IOH_DEBUG
++ ("ioh_1588_pulse_per_sec_time_set:invoking \
++ ioh_1588_pps_imask_set\n");
++ ioh_1588_pps_imask_set();
++ }
++
++ IOH_DEBUG
++ ("ioh_1588_pulse_per_sec_time_set:returning IOH_1588_SUCCESS\n");
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_pulse_per_sec_time_get(
++ * unsigned long *ppsTime)
++ *
++ * @brief Gets the Pulse Per Second match time from the IEEE 1588 hardware
++ * assist block
++ *
++ * @remarks This API will get the PPS match register content
++ * from IEEE 1588 block. The main steps followed in this
++ * function are:
++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL
++ * - Return the time from PPS compare register
++ *
++ *
++ * @param ppsTime [OUT] Buffer for returning the pps match value
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Null parameter passed
++ */
++enum ioh_status ioh_1588_pulse_per_sec_time_get(unsigned long *ppsTime)
++{
++ /* Verify the parameter */
++ if ((unsigned long *)NULL == ppsTime) {
++ IOH_DEBUG("ioh_1588_pulse_per_sec_time_get:invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Retrieve PPS Value */
++ IOH_DEBUG
++ ("ioh_1588_pulse_per_sec_time_get:invoking ioh_1588_pps_get\n");
++ ioh_1588_pps_get(ppsTime);
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_eth_enable(void)
++ *
++ * @brief Sets the eth_enb bit (bit 0) of Ethernet-CAN Select Register
++ * @remarks This API enables the IEEE 1588 hardware time stamping of PTP
++ * traffic
++ * on the Ethernet interface
++ *
++ * @param None
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_eth_enable(void)
++{
++ if (ioh_1588_base != 0) {
++ IOH_DEBUG
++ ("ioh_1588_eth_enable:invoking ioh_1588_eth_enable_set\n");
++ ioh_1588_eth_enable_set();
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_eth_disable(void)
++ *
++ * @brief Clears the eth_enb bit (bit 0) of Ethernet-CAN Select Register
++ * @remarks This API disables the IEEE 1588 hardware time stamping of PTP
++ * traffic
++ * on the Ethernet interface
++ *
++ * @param None
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_eth_disable(void)
++{
++ if (ioh_1588_base != 0) {
++ IOH_DEBUG
++ ("ioh_1588_eth_disable:invoking ioh_1588_eth_enable_clear\n");
++ ioh_1588_eth_enable_clear();
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_can_enable(void)
++ *
++ * @brief Sets the can_enb bit (bit 1) of Ethernet-CAN Select Register
++ * @remraks This API enables the IEEE 1588 hardware time stamping of PTP
++ * traffic
++ * on the CAN interface
++ *
++ * @param None
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_can_enable(void)
++{
++ if (ioh_1588_base != 0) {
++ IOH_DEBUG
++ ("ioh_1588_can_enable:invoking ioh_1588_can_enable_set\n");
++ ioh_1588_can_enable_set();
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_can_disable(void)
++ *
++ * @brief Clear the can_enb bit (bit 1) of Ethernet-CAN Select Register
++ * @remarks This API disables the IEEE 1588 hardware time stamping of PTP
++ * traffic
++ * on the CAN interface
++ *
++ * @param None
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ */
++enum ioh_status ioh_1588_can_disable(void)
++{
++ if (ioh_1588_base != 0) {
++ IOH_DEBUG
++ ("ioh_1588_can_disable:invoking ioh_1588_can_enable_clear\n");
++ ioh_1588_can_enable_clear();
++ }
++
++ return IOH_1588_SUCCESS;
++}
++
++/**
++ * @ingroup IEEE_1588_UtilitiesAPI
++ * @fn static int get_decimal(unsigned char ch)
++ *
++ * @brief Returns the decimal value of the passed
++ * hexadecimal value.
++ *
++ * @note Returns -1 if the passed arguement is invalid.
++ *
++ * @param ch [IN] The hexadecimal value that has to be converted.
++ *
++ * @retval int
++ * - On Success --> decimal Value
++ * - Invalid value --> -1
++ */
++static int get_decimal(unsigned char ch)
++{
++ int ret;
++
++ if ((ch >= '0') && (ch <= '9')) {
++ ret = ch - '0';
++ return ret;
++ } else if ((ch >= 'A') && (ch <= 'F')) {
++ ret = 10 + ch - 'A';
++ return ret;
++ } else if ((ch >= 'a') && (ch <= 'f')) {
++ ret = 10 + ch - 'a';
++ return ret;
++ }
++
++ return -1;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_set_station_address (
++ * unsigned char *addr)
++ *
++ * @brief This API sets the station address used by IEEE 1588 hardware
++ * when looking
++ * at PTP traffic on the ethernet interface
++ *
++ * @param addr [IN] Address which contain the column separated
++ * address to be used
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Invalid address string
++ */
++enum ioh_status ioh_1588_set_station_address(unsigned char *addr)
++{
++ int i;
++
++ /* Verify the parameter */
++ if ((ioh_1588_base == 0) || (unsigned char *)NULL == addr) {
++ IOH_DEBUG("ioh_1588_set_station_address :invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) { /* For all station
++ address bytes */
++ unsigned long val = 0;
++ int tmp;
++
++ tmp = get_decimal(addr[i * 3]);
++ if (tmp < 0) {
++ IOH_DEBUG("ioh_1588_set_station_address :invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++ val = tmp * 16;
++ tmp = get_decimal(addr[(i * 3) + 1]);
++ if (tmp < 0) {
++ IOH_DEBUG("ioh_1588_set_station_address :invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++ val += tmp;
++ if ((i < 5) && (addr[(i * 3) + 2] != ':')) { /* Expects ':'
++ separated addresses */
++ IOH_DEBUG("ioh_1588_set_station_address :invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ /* Ideally we should set the address only after validating
++ entire string */
++ IOH_DEBUG
++ ("ioh_1588_set_station_address \
++ :invoking ioh_1588_station_set\n");
++ ioh_1588_station_set(i, val);
++ }
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_get_station_address(char *addr)
++ * @brief This API gets the station address currently used by IEEE 1588
++ * hardware when looking at PTP traffic on the ethernet interface
++ *
++ * @param addr [OUT] Buffer to which column separated address is
++ * returned
++ * @retval enum ioh_status
++ * @li IOH_1588_SUCCESS - Operation successful
++ * @li IOH_1588_INVALIDPARAM - Null parameter passed
++ */
++enum ioh_status ioh_1588_get_station_address(char *addr)
++{
++ int i;
++
++ /* Verify the parameter */
++ if ((char *)NULL == addr) {
++ IOH_DEBUG("ioh_1588_get_station_address:invalid params\
++ returning IOH_1588_INVALIDPARAM\n");
++ return IOH_1588_INVALIDPARAM;
++ }
++
++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) {
++ unsigned long val = 0;
++
++ ioh_1588_station_get(i, &val);
++ addr[i * 3] = val / 16;
++ if (addr[i * 3] > 9)
++ addr[i * 3] += 'a' - 10;
++ else
++ addr[i * 3] += '0';
++ addr[i * 3 + 1] = val % 16;
++ if (addr[i * 3 + 1] > 9)
++ addr[i * 3 + 1] += 'a' - 10;
++ else
++ addr[i * 3 + 1] += '0';
++ addr[i * 3 + 2] = ':';
++ }
++ addr[17] = '\0';
++ return IOH_1588_SUCCESS;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_target_time_interrupt_enable(
++ * void *callBack)
++ *
++ * @brief This API just returns an error.
++ *
++ * @remarks This API is just for compatibility. It just returns an error.
++ *
++ * @param callBack [IN] Callback to be invoked when interrupt
++ * fires
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_UNSUPPORTED - Operation is not supported
++ */
++enum ioh_status ioh_1588_aux_target_time_interrupt_enable(void *callBack)
++{
++ IOH_DEBUG("ioh_1588_aux_target_time_interrupt_enable:unsupported\n");
++ return IOH_1588_UNSUPPORTED;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_target_time_interrupt_disable(void)
++ *
++ * @brief This API just returns an error.
++ *
++ * @remarks This API is just for compatibility. It just returns an error.
++ *
++ * @param None
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_UNSUPPORTED - Operation is not supported
++ */
++enum ioh_status ioh_1588_aux_target_time_interrupt_disable(void)
++{
++ IOH_DEBUG("ioh_1588_aux_target_time_interrupt_disable:unsupported\n");
++ return IOH_1588_UNSUPPORTED;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_target_time_poll(
++ * unsigned long *attmPollFlag,
++ * struct ioh1588TimeValue *targetTime)
++ *
++ * @brief This API just returns an error.
++ *
++ * @remarks This API is just for compatibility. It just returns an error.
++ *
++ * @param attmPollFlag [OUT] Flag returning the availablity of a
++ * snapshot
++ * @param targetTime [OUT] Snapshot captured
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_UNSUPPORTED - Operation supported
++ */
++enum ioh_status
++ioh_1588_aux_target_time_poll(unsigned long *attmPollFlag,
++ struct ioh1588TimeValue *targetTime)
++{
++ IOH_DEBUG("ioh_1588_aux_target_time_poll:unsupported\n");
++ return IOH_1588_UNSUPPORTED;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_target_time_set(
++ * struct ioh1588TimeValue targetTime)
++ *
++ * @brief This API just returns an error.
++ *
++ * @remarks This API is just for compatibility. It just returns an error.
++ *
++ * @param targetTime [IN] Time to set to
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_UNSUPPORTED - Operation supported
++ */
++enum ioh_status ioh_1588_aux_target_time_set(struct ioh1588TimeValue targetTime)
++{
++ IOH_DEBUG("ioh_1588_aux_target_time_set:unsupported\n");
++ return IOH_1588_UNSUPPORTED;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_target_time_get(
++ * struct ioh1588TimeValue *targetTime)
++ *
++ * @brief This API just returns an error.
++ *
++ * @remarks This API is just for compatibility. It just returns an error.
++ *
++ * @param targetTime [OUT] Buffer for returning time snapshot
++ *
++ *
++ * @retval enum ioh_status
++ * @li IOH_1588_UNSUPPORTED - Operation supported
++ */
++enum ioh_status ioh_1588_aux_target_time_get(
++ struct ioh1588TimeValue *targetTime)
++{
++ IOH_DEBUG("ioh_1588_aux_target_time_get:unsupported\n");
++ return IOH_1588_UNSUPPORTED;
++}
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ *
++ * @fn int ioh_1588_eth_can_get(void)
++ *
++ * @brief This function returns the modes [ethernet/CAN] enabled
++ *
++ * @retval int
++ * - the modes enabled
++ */
++int ioh_1588_eth_can_get(void)
++{
++ int ieee_mode = 0;
++
++ if (ioh_1588_eth_enable_get() == 1)
++ ieee_mode |= IOH_IEEE1588_ETH;
++ if (ioh_1588_can_enable_get() == 1)
++ ieee_mode |= IOH_IEEE1588_CAN;
++
++ return ieee_mode;
++}
++
++#ifdef IOH_IEEE1588_A0_A1_SAMPLE_BUG
++/*! @ingroup IEEE_1588_HALLayerAPI
++ *
++ * @fn void ioh_1588_set_system_time_count(void)
++ *
++ * @brief This function enables all 64 bits in system time registers
++ * [high & low]. This is a work-around for non continuous value
++ * in the SystemTime Register
++ *
++ * @retval none
++ */
++void ioh_1588_set_system_time_count(void)
++{
++ IOH_REG_32_WRITE((ioh_1588_base + 0xC0), 0x1);
++ IOH_REG_32_WRITE((ioh_1588_base + 0xC4), 0xFFFFFFFF);
++ IOH_REG_32_WRITE((ioh_1588_base + 0xC0), 0x0);
++}
++#endif
+diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.h topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.h
+--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.h 1970-01-01 09:00:00.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.h 2010-03-09 07:40:00.000000000 +0900
+@@ -0,0 +1,885 @@
++ /*!
++ * @file ioh_1588_hal.h
++ * @brief
++ * This file lists the declarations of IEEE_1588_HALLayer APIs.
++ * @version 0.92
++ * @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:
++ * modified to support Intel IOH GE IEEE 1588 hardware
++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
++ * All rights reserved.
++ * derived from
++ * IEEE 1588 Time Synchronization Driver for Intel EP80579
++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ * All rights reserved.
++ *
++ */
++
++#ifndef IOH_1588_HAL_H
++#define IOH_1588_HAL_H
++
++#include "pch_1588_main.h"
++
++/* IOH 1588 Hardware Assist Module Register offsets */
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_OFFSET
++@brief TS Control Register Offset
++*/
++#define IOH_1588_TSC_OFFSET (0x00) /* TS_Control */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSE_OFFSET
++@brief TS Event Register Offset
++*/
++#define IOH_1588_TSE_OFFSET (0x04) /* TS_Event */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_ADD_OFFSET
++@brief TS Addend Register Offset
++*/
++#define IOH_1588_ADD_OFFSET (0x08) /* TS_Addend */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_ACC_OFFSET
++@brief TS Accumulator Register Offset
++*/
++#define IOH_1588_ACC_OFFSET (0x0C) /* TS_Accum */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TST_OFFSET
++@brief TS Test Register Offset
++*/
++#define IOH_1588_TST_OFFSET (0x10) /* TS_Test */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_PPS_OFFSET
++@brief TS PPS Compare Register Offset
++*/
++#define IOH_1588_PPS_OFFSET (0x14) /* TS_PPS_Compare */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_STL_OFFSET
++@brief TS System Time Low Register Offset
++*/
++#define IOH_1588_STL_OFFSET (0x20) /* TS_SysTimeLo */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_STH_OFFSET
++@brief TS System Time High Register Offset
++*/
++#define IOH_1588_STH_OFFSET (0x24) /* TS_SysTimeHi */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TTL_OFFSET
++@brief TS Target Time Low Register Offset
++*/
++#define IOH_1588_TTL_OFFSET (0x28) /* TS_TrgtLo */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TTH_OFFSET
++@brief TS Target Time High Register Offset
++*/
++#define IOH_1588_TTH_OFFSET (0x2c) /* TS_TrgtHi */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_ASSL_OFFSET
++@brief TS Aux Slave Mode Snapshot Low Register Offset
++*/
++#define IOH_1588_ASSL_OFFSET (0x30) /* TS_ASMSLo */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_ASSH_OFFSET
++@brief TS Aux Slave Mode Snapshot High Register Offset
++*/
++#define IOH_1588_ASSH_OFFSET (0x34) /* TS_ASMSHi */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_ASSH_OFFSET
++@brief TS Aux Master Mode Snapshot Low Register Offset
++*/
++#define IOH_1588_AMSL_OFFSET (0x38) /* TS_AMMSLo */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_AMSH_OFFSET
++@brief TS Aux Master Mode Snapshot High Register Offset
++*/
++#define IOH_1588_AMSH_OFFSET (0x3C) /* TS_AMMSHi */
++
++/* Ethernet */
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CC_OFFSET
++@brief TS Channel Control Register Offset
++*/
++#define IOH_1588_CC_OFFSET (0x40) /* TS_Ch_Contr */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CE_OFFSET
++@brief TS Channel Event Register Offset
++*/
++#define IOH_1588_CE_OFFSET (0x44) /* TS_Ch_Event */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_XSL_OFFSET
++@brief TS Tx Snapshot Low Register Offset
++*/
++#define IOH_1588_XSL_OFFSET (0x48) /* TS_TxSnapLo */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_XSH_OFFSET
++@brief TS Tx Snapshot High Register Offset
++*/
++#define IOH_1588_XSH_OFFSET (0x4C) /* TS_TxSnapHi */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_RSL_OFFSET
++@brief TS Rx Snapshot Low Register Offset
++*/
++#define IOH_1588_RSL_OFFSET (0x50) /* TS_RxSnapLo */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_RSH_OFFSET
++@brief TS Rx Snapshot High Register Offset
++*/
++#define IOH_1588_RSH_OFFSET (0x54) /* TS_RxSnapHi */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_UID_OFFSET
++@brief TS Source UUID Low Register Offset
++*/
++#define IOH_1588_UID_OFFSET (0x58) /* TS_SrcUUID */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_SID_OFFSET
++@brief TS Source UUID High/SequenceID Register Offset
++*/
++#define IOH_1588_SID_OFFSET (0x5C) /* TS_SrcUUID */
++
++/* CAN */
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CCE_OFFSET
++@brief TS CAN Channel Status Register Offset
++*/
++#define IOH_1588_CCE_OFFSET (0x60) /* TS_CAN_Stat */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CXSL_OFFSET
++@brief TS CAN Snapshot Low Register Offset
++*/
++#define IOH_1588_CXSL_OFFSET (0x64) /* TS_CAN_Snap */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CXSH_OFFSET
++@brief TS CAN Snapshot High Register Offset
++*/
++#define IOH_1588_CXSH_OFFSET (0x68) /* TS_CAN_Snap */
++
++/* Selector */
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_ECS_OFFSET
++@brief TS Ethernet/CAN Select Register Offset
++*/
++#define IOH_1588_ECS_OFFSET (0x6c) /* TS_SEL */
++
++/* Station Address 1-6 */
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_STA_OFFSET
++@brief TS Station Address Register Offset
++*/
++#define IOH_1588_STA_OFFSET (0x70) /* TS_ST1 */
++
++/* Bit Masks of Control Register */
++/* Hardware Assist Reset */
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_RESET_SHIFT
++@brief Reset Bit position in Control Register
++*/
++#define IOH_1588_TSC_RESET_SHIFT 0
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_RESET
++@brief Bit Maks for Reset Bit in Control Register
++*/
++#define IOH_1588_TSC_RESET (1 << IOH_1588_TSC_RESET_SHIFT)
++
++/* Target Time Interrupt Mask */
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_TIM_SHIFT
++@brief Bit position of Target Time Interrupt Bit in Control
++ Register
++*/
++#define IOH_1588_TSC_TTM_SHIFT 1
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_TIM_MASK
++@brief Bit Mask for Target Time Interrupt in Control Register
++*/
++#define IOH_1588_TSC_TTM_MASK (1 << IOH_1588_TSC_TTM_SHIFT)
++
++/* Auxiliary Slave Mode snapshot Interrupt Mask */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_ASMS_SHIFT
++@brief Bit position of Aux Slave Mode snapshot
++ Interrupt in Control Register
++*/
++#define IOH_1588_TSC_ASMS_SHIFT 2
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_ASMS_MASK
++@brief Bit Mask for Aux Slave Mode snapshot
++ Interrupt in Control Register
++*/
++#define IOH_1588_TSC_ASMS_MASK (1 << IOH_1588_TSC_ASMS_SHIFT)
++
++/* Auxiliary Master Mode snapshot Interrupt Mask */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_AMMS_SHIFT
++@brief Bit position for for Aux Master Mode snapshot
++ Interrupt in Control Register
++*/
++#define IOH_1588_TSC_AMMS_SHIFT 3
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_AMMS_MASK
++@brief Bit mask for for Aux Master Mode snapshot
++ Interrupt in Control Register
++*/
++#define IOH_1588_TSC_AMMS_MASK (1 << IOH_1588_TSC_AMMS_SHIFT)
++
++/* Pulse Per Second Interrupt Mask */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_PPSM_SHIFT
++@brief Bit position of Pulse Per Second
++ Interrupt in Control Register
++*/
++#define IOH_1588_TSC_PPSM_SHIFT 4
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSC_PPSM_MASK
++@brief Bit mask of Pulse Per Second
++ Interrupt in Control Register
++*/
++#define IOH_1588_TSC_PPSM_MASK (1 << IOH_1588_TSC_PPSM_SHIFT)
++
++/* Bit Masks of Event Register */
++/* Target Time Interrupt Pending Event */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSE_TTIPEND_SHIFT
++@brief Bit position of Target Time Interrupt
++ Pending in Event Register
++*/
++#define IOH_1588_TSE_TTIPEND_SHIFT 1
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSE_TTIPEND
++@brief Bit mask of Target Time Interrupt
++ Pending in Event Register
++*/
++#define IOH_1588_TSE_TTIPEND (1 << IOH_1588_TSE_TTIPEND_SHIFT)
++
++/* Auxiliary Slave Mode snapshot Event */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSE_SNS_SHIFT
++@brief Bit position of Aux Slave Mode snapshot
++ in Event Register
++*/
++#define IOH_1588_TSE_SNS_SHIFT 2
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSE_SNS
++@brief Bit mask of Aux Slave Mode snapshot
++ in Event Register
++*/
++#define IOH_1588_TSE_SNS (1 << IOH_1588_TSE_SNS_SHIFT)
++
++/* Auxiliary Master Mode snapshot Event */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSE_SNM_SHIFT
++@brief Bit position of Aux Master Mode snapshot
++ in Event Register
++*/
++#define IOH_1588_TSE_SNM_SHIFT 3
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSE_SNM
++@brief Bit mask of Aux Master Mode snapshot
++ in Event Register
++*/
++#define IOH_1588_TSE_SNM (1 << IOH_1588_TSE_SNM_SHIFT)
++
++/* Pulse Per Second Match */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSE_PPS_SHIFT
++@brief Bit position of Pusle Per Second Match
++ in Event Register
++*/
++#define IOH_1588_TSE_PPS_SHIFT 4
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_TSE_PPS
++@brief Bit mask of Pusle Per Second Match
++ in Event Register
++*/
++#define IOH_1588_TSE_PPS (1 << IOH_1588_TSE_PPS_SHIFT)
++
++/* Bit Masks of Channel Control Register */
++/* Timestamp Master or Slave Mode Control Flag */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CC_MM_SHIFT
++@brief Bit position of Timestamp Master/Slave Mode
++ in Channel Control Register
++*/
++#define IOH_1588_CC_MM_SHIFT 0
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CC_MM
++@brief Bit mask of Timestamp Master/Slave Mode
++ control flag in
++ in Channel Control Register
++*/
++#define IOH_1588_CC_MM (1 << IOH_1588_CC_MM_SHIFT)
++
++/* Timestamp All Messages Control Flag */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CC_TA_SHIFT
++@brief Bit position of Timestamp all messages
++ Mode control flag
++ in Channel Control Register
++*/
++#define IOH_1588_CC_TA_SHIFT 1
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CC_TA
++@brief Bit mask of Timestamp all messages
++ Mode control flag
++ in Channel Control Register
++*/
++#define IOH_1588_CC_TA (1 << IOH_1588_CC_TA_SHIFT)
++
++/* Mode bits */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CC_MODE_SHIFT
++@brief Bit position of mode bits
++ in Channel Control Register
++*/
++#define IOH_1588_CC_MODE_SHIFT 16
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CC_MODE_MASK
++@brief Bit mask for mode bits
++ in Channel Control Register
++*/
++#define IOH_1588_CC_MODE_MASK (0x001F0000)
++
++/* Version bit */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CC_VERSION_SHIFT
++@brief Bit position for version bits
++ in Channel Control Register
++*/
++#define IOH_1588_CC_VERSION_SHIFT 31
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CC_VERSION
++@brief Bit mask for version bits
++ in Channel Control Register
++*/
++#define IOH_1588_CC_VERSION (1 << IOH_1588_CC_VERSION_SHIFT)
++
++/* Bit Masks of Channel Event Register */
++/* Transmit Snapshot Locked Indicator Flag */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CE_TXS
++@brief Bit mask for Transmit Snapshot Locked bit
++ in Channel Event Register
++*/
++#define IOH_1588_CE_TXS (1 << 0)
++
++/* Receive Snapshot Locked Indicator Flag */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CE_TXS
++@brief Bit mask for Receive Snapshot Locked bit
++ in Channel Event Register
++*/
++#define IOH_1588_CE_RXS (1 << 1)
++
++/* Bit Masks of CAN Channel Event Register */
++/* Overrun Indicator Flag */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CE_OVR
++@brief Bit mask for Overrun Indicator bit
++ in Channel Event Register
++*/
++#define IOH_1588_CE_OVR (1 << 0)
++
++/* Valid Indicator Flag */
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_CE_VAL
++@brief Bit mask for Valid Indicator bit
++ in Channel Event Register
++*/
++#define IOH_1588_CE_VAL (1 << 1)
++
++/* Ethernet Enable bit */
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_ECS_ETH_SHIFT
++@brief Bit position for Ethernet Enable bit
++ in Ethernet/CAN select Register
++*/
++#define IOH_1588_ECS_ETH_SHIFT 0
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_ECS_ETH
++@brief Bit mask for Ethernet Enable bit
++ in Ethernet/CAN select Register
++*/
++#define IOH_1588_ECS_ETH (1 << IOH_1588_ECS_ETH_SHIFT)
++/* Can Enable bit */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_ECS_CAN_SHIFT
++@brief Bit position for CAN Enable bit
++ in Ethernet/CAN select Register
++*/
++#define IOH_1588_ECS_CAN_SHIFT 1
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_ECS_CAN
++@brief Bit mask for CAN Enable bit
++ in Ethernet/CAN select Register
++*/
++#define IOH_1588_ECS_CAN (1 << IOH_1588_ECS_CAN_SHIFT)
++
++/* Station Address bytes */
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def IOH_1588_STATION_BYTES
++@brief Bytes for Station Address
++*/
++#define IOH_1588_STATION_BYTES 6
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@def DRIVER_NAME
++@brief The name of this driver
++*/
++#define DRIVER_NAME "ioh_ieee1588"
++
++#define IOH_IEEE1588_ETH (1 << 0)
++#define IOH_IEEE1588_CAN (1 << 1)
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@typedef typedef void (*ioh1588TargetTimeCallback)
++ (struct ioh1588TimeValue tgt_time)
++@brief Pointer for Callback function for Target Time interrupt
++@see
++ - ioh_1588_blpl_base_address_set
++ - ioh_1588_target_time_interrupt_enable
++ - ioh_1588_target_time_interrupt_disable
++ - ioh_1588_target_time_poll
++ - ioh_1588_reset
++*/
++typedef void (*ioh1588TargetTimeCallback) (struct ioh1588TimeValue tgt_time);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@typedef typedef void (*ioh1588AuxTimeCallback)
++ (enum ioh1588AuxMode aux_mode,
++ struct ioh1588TimeValue aux_time)
++@brief Pointer for Callback function for Aux Time interrupt
++@see
++ - ioh_1588_blpl_base_address_set
++ - ioh_1588_aux_time_interrupt_enable
++ - ioh_1588_aux_time_interrupt_disable
++ - ioh_1588_aux_time_poll
++ - ioh_1588_reset
++*/
++typedef void (*ioh1588AuxTimeCallback) (enum ioh1588AuxMode aux_mode,
++ struct ioh1588TimeValue aux_time);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++@typedef typedef void (*ioh1588PulsePerSecondCallback)(
++ unsigned long pps)
++@brief Pointer for Callback function for Pulse Per Second
++ interrupt
++@see
++ - ioh_1588_blpl_base_address_set
++ - ioh_1588_pulse_per_sec_interrupt_enable
++ - ioh_1588_pulse_per_sec_interrupt_disable
++ - ioh_1588_reset
++*/
++typedef void (*ioh1588PulsePerSecondCallback) (unsigned long pps);
++
++/**
++ * prototypes of HAL APIs
++ */
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_blpl_base_address_set(unsigned long base_addr)
++ */
++enum ioh_status ioh_1588_blpl_base_address_set(unsigned long base_addr);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_port_config_set(
++ * enum ioh1588PTPPort ptpPort,
++ * enum ioh1588PTPPortMode ptpPortMode)
++ */
++enum ioh_status
++ioh_1588_ptp_port_config_set(enum ioh1588PTPPort ptpPort,
++ enum ioh1588PTPPortMode ptpPortMode);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_port_config_get(
++ * enum ioh1588PTPPort ptpPort,
++ * enum ioh1588PTPPortMode *ptpPortMode)
++ */
++enum ioh_status
++ioh_1588_ptp_port_config_get(enum ioh1588PTPPort ptpPort,
++ enum ioh1588PTPPortMode *ptpPortMode);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_rx_poll(
++ * enum ioh1588PTPPort ptpPort,
++ * struct ioh1588PtpMsgData *ptpMsgData)
++ *
++ *
++ */
++enum ioh_status
++ioh_1588_ptp_rx_poll(
++ enum ioh1588PTPPort ptpPort, \
++ struct ioh1588PtpMsgData *ptpMsgData);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_tx_poll(
++ * enum ioh1588PTPPort ptpPort,
++ * struct ioh1588PtpMsgData *ptpMsgData)
++ *
++ */
++enum ioh_status
++ioh_1588_ptp_tx_poll(
++ enum ioh1588PTPPort ptpPort, \
++ struct ioh1588PtpMsgData *ptpMsgData);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_system_time_set(
++ * struct ioh1588TimeValue systemTime)
++ *
++ */
++enum ioh_status ioh_1588_system_time_set(struct ioh1588TimeValue systemTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_system_time_get(
++ * struct ioh1588TimeValue *systemTime)
++ *
++ */
++enum ioh_status ioh_1588_system_time_get(struct ioh1588TimeValue *systemTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_tick_rate_set(unsigned long tickRate)
++ *
++ */
++enum ioh_status ioh_1588_tick_rate_set(unsigned long tickRate);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_tick_rate_get(unsigned long *tickRate)
++ *
++ */
++enum ioh_status ioh_1588_tick_rate_get(unsigned long *tickRate);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_target_time_interrupt_enable(
++ * ioh1588TargetTimeCallback callBack)
++ *
++ */
++enum ioh_status
++ioh_1588_target_time_interrupt_enable(ioh1588TargetTimeCallback callBack);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_target_time_interrupt_disable(void)
++ *
++ */
++enum ioh_status ioh_1588_target_time_interrupt_disable(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_target_time_poll(
++ * unsigned long *ttmPollFlag,
++ * struct ioh1588TimeValue *targetTime)
++ *
++ */
++enum ioh_status
++ioh_1588_target_time_poll(unsigned long *ttmPollFlag,
++ struct ioh1588TimeValue *targetTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_target_time_set(
++ * struct ioh1588TimeValue targetTime)
++ *
++ */
++enum ioh_status ioh_1588_target_time_set(struct ioh1588TimeValue targetTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_target_time_get(
++ * struct ioh1588TimeValue *targetTime)
++ *
++ */
++enum ioh_status ioh_1588_target_time_get(struct ioh1588TimeValue *targetTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_time_interrupt_enable(
++ enum ioh1588AuxMode auxMode,
++ * ioh1588AuxTimeCallback callBack)
++ *
++ */
++enum ioh_status
++ioh_1588_aux_time_interrupt_enable(enum ioh1588AuxMode auxMode,
++ ioh1588AuxTimeCallback callBack);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_time_interrupt_disable(
++ enum ioh1588AuxMode auxMode)
++ *
++ */
++enum ioh_status ioh_1588_aux_time_interrupt_disable(
++ enum ioh1588AuxMode auxMode);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_time_poll(
++ * enum ioh1588AuxMode auxMode,
++ * unsigned long *pollFlag,
++ * struct ioh1588TimeValue *auxTime)
++ *
++ */
++enum ioh_status
++ioh_1588_aux_time_poll(enum ioh1588AuxMode auxMode,
++ unsigned long *pollFlag,
++ struct ioh1588TimeValue *auxTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_reset(void)
++ *
++ */
++enum ioh_status ioh_1588_reset(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_chnl_reset(enum ioh1588PTPPort ptpPort)
++ *
++ */
++enum ioh_status ioh_1588_chnl_reset(enum ioh1588PTPPort ptpPort);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_stats_get(struct ioh1588Stats *stats)
++ *
++ */
++enum ioh_status ioh_1588_stats_get(struct ioh1588Stats *stats);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn void ioh_1588_stats_reset(void)
++ *
++ */
++void ioh_1588_stats_reset(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn void ioh_1588_show(void)
++ *
++ */
++enum ioh_status ioh_1588_show(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_pulse_per_sec_interrupt_enable(
++ * ioh1588PulsePerSecondCallback callBack)
++ *
++ */
++enum ioh_status
++ioh_1588_pulse_per_sec_interrupt_enable(ioh1588PulsePerSecondCallback callBack);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_pulse_per_sec_interrupt_disable(void)
++ *
++ */
++enum ioh_status ioh_1588_pulse_per_sec_interrupt_disable(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_pulse_per_sec_time_get(unsigned long *ppsTime)
++ *
++ */
++enum ioh_status ioh_1588_pulse_per_sec_time_get(unsigned long *ppsTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_pulse_per_sec_time_set(unsigned long ppsTime)
++ *
++ */
++enum ioh_status ioh_1588_pulse_per_sec_time_set(unsigned long ppsTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_can_poll (
++ * enum ioh1588PTPPort ptpPort,
++ * struct ioh1588TimeValue *ptpTimeStamp)
++ *
++ */
++enum ioh_status ioh_1588_ptp_can_poll(enum ioh1588PTPPort ptpPort,
++ struct ioh1588TimeValue *ptpTimeStamp);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_version_get(enum ioh1588PTPPort ptpPort,
++ * enum ioh1588PTPVersion *ptpVersion)
++ *
++ */
++enum ioh_status
++ioh_1588_ptp_version_get(enum ioh1588PTPPort ptpPort,
++ enum ioh1588PTPVersion *ptpVersion);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_version_set(enum ioh1588PTPPort ptpPort,
++ * enum ioh1588PTPVersion ptpVersion)
++ *
++ */
++enum ioh_status
++ioh_1588_ptp_version_set(
++ enum ioh1588PTPPort ptpPort, \
++ enum ioh1588PTPVersion ptpVersion);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_operation_mode_set(
++ * enum ioh1588PTPPort ptpPort,
++ * enum ioh1588PTPOperationMode ptpMode)
++ *
++ */
++enum ioh_status
++ioh_1588_ptp_operation_mode_set(enum ioh1588PTPPort ptpPort,
++ enum ioh1588PTPOperationMode ptpMode);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_ptp_operation_mode_get(enum ioh1588PTPPort ptpPort,
++ * enum ioh1588PTPOperationMode *ptpMode)
++ */
++enum ioh_status
++ioh_1588_ptp_operation_mode_get(enum ioh1588PTPPort ptpPort,
++ enum ioh1588PTPOperationMode *ptpMode);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_handler(void)
++ *
++ */
++enum ioh_status ioh_1588_handler(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_target_time_interrupt_enable(void *callBack)
++ *
++ */
++enum ioh_status ioh_1588_aux_target_time_interrupt_enable(void *callBack);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_target_time_interrupt_disable(void)
++ *
++ */
++enum ioh_status ioh_1588_aux_target_time_interrupt_disable(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_target_time_poll(
++ * unsigned long *attmPollFlag, struct ioh1588TimeValue *targetTime)
++ *
++ */
++enum ioh_status
++ioh_1588_aux_target_time_poll(unsigned long *attmPollFlag,
++ struct ioh1588TimeValue *targetTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_target_time_set(
++ * struct ioh1588TimeValue targetTime)
++ *
++ */
++enum ioh_status ioh_1588_aux_target_time_set(
++ struct ioh1588TimeValue targetTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_aux_target_time_get(
++ * struct ioh1588TimeValue *targetTime)
++ *
++ */
++enum ioh_status ioh_1588_aux_target_time_get(
++ struct ioh1588TimeValue *stargetTime);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_disable_interrupts(void)
++ *
++ */
++enum ioh_status ioh_1588_disable_interrupts(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_interrupt_pending(unsigned long *pending)
++ *
++ */
++enum ioh_status ioh_1588_interrupt_pending(unsigned long *pending);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_eth_enable(void)
++ *
++ */
++enum ioh_status ioh_1588_eth_enable(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_eth_disable(void)
++ *
++ */
++enum ioh_status ioh_1588_eth_disable(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_can_enable(void)
++ *
++ */
++enum ioh_status ioh_1588_can_enable(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_can_disable(void)
++ *
++ */
++enum ioh_status ioh_1588_can_disable(void);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_set_station_address (unsigned char *addr)
++ *
++ */
++enum ioh_status ioh_1588_set_station_address(unsigned char *addr);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn enum ioh_status ioh_1588_get_station_address(char *addr)
++ *
++ */
++enum ioh_status ioh_1588_get_station_address(char *addr);
++
++/*! @ingroup IEEE_1588_HALLayerAPI
++ * @fn int ioh_1588_eth_can_get(void)
++ *
++ */
++int ioh_1588_eth_can_get(void);
++
++#ifdef IOH_IEEE1588_A0_A1_SAMPLE_BUG
++void ioh_1588_set_system_time_count(void);
++#endif
++
++#endif /* IOH_1588_HAL_H */
+diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.c topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.c
+--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.c 1970-01-01 09:00:00.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.c 2010-03-09 10:33:42.000000000 +0900
+@@ -0,0 +1,1192 @@
++ /*!
++ * @file ioh_1588_main.c
++ * @brief
++ * This file contains the definitions of the IEEE_1588_InterfaceLayer APIs
++ * @version 0.92
++ * @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:
++ * modified to support Intel IOH GE IEEE 1588 hardware
++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
++ * All rights reserved.
++ * derived from
++ * IEEE 1588 Time Synchronization Driver for Intel EP80579
++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ * All rights reserved.
++ */
++
++#include "pch_1588_pci.h"
++#include "pch_1588_main.h"
++#include "pch_1588_hal.h"
++#include "pch_debug.h"
++#include <linux/sched.h>
++
++/* Linux functions prototypes */
++static int ioh_1588_open(struct inode *inode, struct file *filep);
++static int ioh_1588_release(struct inode *inode, struct file *filep);
++static int ioh_1588_ioctl(struct inode *inode, struct file *filep,
++ unsigned int cmd, unsigned long arg);
++
++/* Linux file operations */
++/*! @ingroup IEEE_1588_Global
++ * @var ioh_1588_fops
++ * @brief The structure variable used to specify the
++ * driver specific functionalities to the kernel
++ * subsystem.
++*/
++const struct file_operations ioh_1588_fops = {
++ .owner = THIS_MODULE,
++ .open = ioh_1588_open,
++ .release = ioh_1588_release,
++ .ioctl = ioh_1588_ioctl,
++};
++
++/* For notify ioctls - values are populated from isr callbacks */
++/*! @ingroup IEEE_1588_Global
++ * @var ioh_1588_target_time
++ * @brief This variable is updated from the target time reached callback
++ */
++struct ioh1588TimeValue ioh_1588_target_time;
++/*! @ingroup IEEE_1588_Global
++ * @var ioh_1588_aux_time
++ * @brief This variable is updated from the Auxiliary master/slave time
++ * captured callback
++ */
++struct ioh1588AuxTimeIoctl ioh_1588_aux_time;
++/*! @ingroup IEEE_1588_Global
++ * @var ioh_1588_pps_time
++ * @brief This variable is updated from the Pulse per second match
++ * callback
++ */
++unsigned long ioh_1588_pps_time;
++
++typedef int (*ioc_func_ptr) (unsigned long cmd, char *arg);
++static int ioc_handle_notify(unsigned long cmd, char *buf);
++static int ioc_handle_clr_notify(unsigned long cmd, char *buf);
++static int ioc_handle_reset(unsigned long cmd, char *buf);
++static int ioc_handle_show(unsigned long cmd, char *buf);
++static int ioc_handle_stats(unsigned long cmd, char *buf);
++static int ioc_handle_stats_reset(unsigned long cmd, char *buf);
++static int ioc_handle_int_enable(unsigned long cmd, char *buf);
++static int ioc_handle_int_disable(unsigned long cmd, char *buf);
++static int ioc_handle_port_config(unsigned long cmd, char *buf);
++static int ioc_handle_poll(unsigned long cmd, char *buf);
++static int ioc_handle_time_set(unsigned long cmd, char *buf);
++static int ioc_handle_time_get(unsigned long cmd, char *buf);
++static int ioc_handle_tick_rate(unsigned long cmd, char *buf);
++static int ioc_handle_pps_reqt(unsigned long cmd, char *buf);
++static int ioc_handle_version_reqt(unsigned long cmd, char *buf);
++static int ioc_handle_op_mode_reqt(unsigned long cmd, char *buf);
++
++/* IOCTL command and their associated functions */
++
++/*! @ingroup IEEE_1588_Global
++ * @struct ioh_1588_ioc_tbl
++ * @brief Structure to map the ioctl command to the associated function
++ */
++static const struct ioh_1588_ioc_tbl {
++ unsigned long cmd;
++ ioc_func_ptr func;
++} ioh_1588_ioc_tbl[] = {
++ {
++ IOCTL_1588_TARG_TIME_NOTIFY, ioc_handle_notify}, {
++ IOCTL_1588_AUX_TIME_NOTIFY, ioc_handle_notify}, {
++ IOCTL_1588_PULSE_PER_SEC_NOTIFY, ioc_handle_notify}, {
++ IOCTL_1588_AUX_TARG_TIME_NOTIFY, ioc_handle_notify}, {
++ IOCTL_1588_TARG_TIME_CLR_NOTIFY, ioc_handle_clr_notify}, {
++ IOCTL_1588_AUX_TIME_CLR_NOTIFY, ioc_handle_clr_notify}, {
++ IOCTL_1588_PULSE_PER_SEC_CLR_NOTIFY, ioc_handle_clr_notify}, {
++ IOCTL_1588_AUX_TARG_TIME_CLR_NOTIFY, ioc_handle_clr_notify}, {
++ IOCTL_1588_RESET, ioc_handle_reset}, {
++ IOCTL_1588_CHNL_RESET, ioc_handle_reset}, /* for this case too */
++ {
++ IOCTL_1588_SHOW_ALL, ioc_handle_show}, {
++ IOCTL_1588_STATS_GET, ioc_handle_stats}, {
++ IOCTL_1588_STATS_RESET, ioc_handle_stats_reset}, {
++ IOCTL_1588_TARG_TIME_INTRPT_ENABLE, ioc_handle_int_enable}, {
++ IOCTL_1588_AUX_TIME_INTRPT_ENABLE, ioc_handle_int_enable}, {
++ IOCTL_1588_PULSE_PER_SEC_INTRPT_ENABLE, ioc_handle_int_enable}, {
++ IOCTL_1588_AUX_TARG_TIME_INTRPT_ENABLE, ioc_handle_int_enable}, {
++ IOCTL_1588_TARG_TIME_INTRPT_DISABLE, ioc_handle_int_disable}, {
++ IOCTL_1588_AUX_TIME_INTRPT_DISABLE, ioc_handle_int_disable}, {
++ IOCTL_1588_PULSE_PER_SEC_INTRPT_DISABLE, ioc_handle_int_disable}, {
++ IOCTL_1588_AUX_TARG_TIME_INTRPT_DISABLE, ioc_handle_int_disable}, {
++ IOCTL_1588_PORT_CONFIG_SET, ioc_handle_port_config}, {
++ IOCTL_1588_PORT_CONFIG_GET, ioc_handle_port_config}, {
++ IOCTL_1588_RX_POLL, ioc_handle_poll}, {
++ IOCTL_1588_TX_POLL, ioc_handle_poll}, {
++ IOCTL_1588_CAN_POLL, ioc_handle_poll}, {
++ IOCTL_1588_TARG_TIME_POLL, ioc_handle_poll}, {
++ IOCTL_1588_AUX_TIME_POLL, ioc_handle_poll}, {
++ IOCTL_1588_AUX_TARG_TIME_POLL, ioc_handle_poll}, {
++ IOCTL_1588_SYS_TIME_SET, ioc_handle_time_set}, {
++ IOCTL_1588_TARG_TIME_SET, ioc_handle_time_set}, {
++ IOCTL_1588_AUX_TARG_TIME_SET, ioc_handle_time_set}, {
++ IOCTL_1588_SYS_TIME_GET, ioc_handle_time_get}, {
++ IOCTL_1588_TARG_TIME_GET, ioc_handle_time_get}, {
++ IOCTL_1588_AUX_TARG_TIME_GET, ioc_handle_time_get}, {
++ IOCTL_1588_TICK_RATE_GET, ioc_handle_tick_rate}, {
++ IOCTL_1588_TICK_RATE_SET, ioc_handle_tick_rate}, {
++ IOCTL_1588_PULSE_PER_SEC_TIME_SET, ioc_handle_pps_reqt}, {
++ IOCTL_1588_PULSE_PER_SEC_TIME_GET, ioc_handle_pps_reqt}, {
++ IOCTL_1588_PORT_VERSION_SET, ioc_handle_version_reqt}, {
++ IOCTL_1588_PORT_VERSION_GET, ioc_handle_version_reqt}, {
++ IOCTL_1588_PORT_OPERATION_MODE_SET, ioc_handle_op_mode_reqt}, {
++IOCTL_1588_PORT_OPERATION_MODE_GET, ioc_handle_op_mode_reqt},};
++
++#define IOH_1588_IOC_TBL_ENTRIES \
++ (sizeof ioh_1588_ioc_tbl / sizeof ioh_1588_ioc_tbl[0])
++
++/*! @ingroup IEEE_1588_InterfaceLayerAPI
++ * @fn int ioh_1588_open(struct inode *inode, struct file *filep)
++ * @brief This function is called when the driver interface is opened
++ * @remarks This function is registered at the driver initialization
++ * point (module_init) and invoked when a process opens the
++ * IEEE 1588 device node.
++ *
++ * @param inode [IN] pointer to device inode structure
++ * @param filep [IN] pointer to open file structure
++ *
++ * @return int
++ * - Returns 0 on success and <0 on failure
++ */
++static int ioh_1588_open(struct inode *inode, struct file *filep)
++{
++ if (ioh_1588_devp->suspend) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_open returning as device is suspended\n");
++ return -EINTR;
++ }
++ IOH_DEBUG("ioh_1588_open\n");
++
++ return 0;
++}
++
++/*! @ingroup IEEE_1588_InterfaceLayerAPI
++ * @fn int ioh_1588_release(struct inode *inode, struct file *filep)
++ * @brief This function is called when the driver interface is closed
++ * @remarks This function is registered at the driver initialization
++ * point (module_init) and invoked when the last process
++ * which has an open file table entry for the device
++ * exits or does a close of the device file.
++ *
++ * @param inode [IN] pointer to device inode structure
++ * @param filep [IN] pointer to open file structure
++ *
++ * @retval int
++ * - Returns 0 on success and <0 on failure
++ */
++static int ioh_1588_release(struct inode *inode, struct file *filep)
++{
++ IOH_DEBUG("ioh_1588_release\n");
++
++ return 0;
++}
++
++/*! @ingroup IEEE_1588_InterfaceLayerAPI
++ * @fn int ioh_1588_ioctl(struct inode *inode, struct file *filep,
++ * unsigned int cmd, unsigned long arg)
++ * @brief This function implements the ioctl interface of the driver
++ * @remarks This function is registered at the driver initialization
++ * point (module_init) and invoked when a user process
++ * invokes the .ioctl. call on the device
++ *
++ * @param inode [IN] pointer to device inode structure
++ * @param filep [IN] pointer to open file structure
++ * @param cmd [IN] ioctl command
++ * @param arg [INOUT] argument passed to the command
++ *
++ * @retval int
++ * - Returns 0 on success and <0 on failure
++ */
++static int ioh_1588_ioctl(struct inode *inode, struct file *filep,
++ unsigned int cmd, unsigned long arg)
++{
++ char buffer[0x64];
++ unsigned int argsz;
++ int i, ret = 0;
++
++ if ((!ioh_1588_devp->initialized) || (ioh_1588_devp->suspend)) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl:device is suspended OR \
++ uninitialized\n");
++ return -EINTR;
++ }
++
++ argsz = _IOC_SIZE(cmd);
++
++ if (argsz > sizeof buffer) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: buffer size too small.\n");
++ return -EINVAL;
++ }
++
++ /* if data is being written to the driver */
++ if (_IOC_DIR(cmd) & _IOC_WRITE) {
++ /* get the data passed in by user */
++ if (copy_from_user(&buffer, (void *)arg, argsz)) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: could not copy user space \
++ data.\n");
++ return -EFAULT;
++ }
++ }
++
++ for (i = 0; i < IOH_1588_IOC_TBL_ENTRIES; i++) {
++ if (ioh_1588_ioc_tbl[i].cmd == cmd) {
++ ret = ioh_1588_ioc_tbl[i].func(cmd, buffer);
++ break;
++ }
++ }
++ if (i >= IOH_1588_IOC_TBL_ENTRIES) { /* did not find a match */
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: unknown command (0x%x)\n",
++ cmd);
++ return -EINVAL;
++ }
++
++ /* if data is being read from the driver */
++ if ((ret == 0) && (_IOC_DIR(cmd) & _IOC_READ)) {
++ if (copy_to_user((void *)arg, buffer, argsz)) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: could not copy data to user \
++ space.\n");
++ return -EFAULT;
++ }
++ }
++
++ return ret;
++}
++
++/* Handles all NOTIFY IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_notify (unsigned long cmd, char *buf)
++ * @brief Handles all NOTIFY IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [OUT] the reference to data to be returned
++ * @retval int
++ * - 0
++ * <hr>
++ */
++static int ioc_handle_notify(unsigned long cmd, char *buf)
++{
++ unsigned int bytes_ret = 0;
++ void *param_addr = NULL;
++ wait_queue_head_t *event = NULL;
++ unsigned int eventnum = 0;
++
++ if (IOCTL_1588_AUX_TARG_TIME_NOTIFY == cmd) {
++ IOH_LOG(KERN_ERR, "ioc_handle_notify \
++ returning...[cmd = IOCTL_1588_AUX_TARG_TIME_NOTIFY]\n");
++ return -EINVAL;
++ }
++ /* request to be notified of a 1588 interrupt event Target Time */
++ else if (cmd == IOCTL_1588_TARG_TIME_NOTIFY) {
++ IOH_DEBUG
++ ("ioc_handle_notify cmd = IOCTL_1588_TARG_TIME_NOTIFY]\n");
++ event = &ioh_1588_devp->notify_evt[TARG_TIME_EVENT_NUM];
++ bytes_ret = sizeof(struct ioh1588TimeValue);
++ param_addr = &ioh_1588_target_time;
++ eventnum = TARG_TIME_EVENT_NUM;
++ } else if (cmd == IOCTL_1588_AUX_TIME_NOTIFY) {
++ IOH_DEBUG
++ ("ioc_handle_notify cmd = IOCTL_1588_AUX_TIME_NOTIFY]\n");
++ event = &ioh_1588_devp->notify_evt[AUX_TIME_EVENT_NUM];
++ bytes_ret = sizeof(struct ioh1588AuxTimeIoctl);
++ param_addr = &ioh_1588_aux_time;
++ eventnum = AUX_TIME_EVENT_NUM;
++ } else {
++ event = &ioh_1588_devp->notify_evt[PPS_EVENT_NUM];
++ bytes_ret = sizeof(unsigned long);
++ param_addr = &ioh_1588_pps_time;
++ eventnum = PPS_EVENT_NUM;
++ }
++
++ ioh_1588_devp->event_flags[eventnum] = 0;
++
++ /* wait infinitely for a 1588 interrupt event to occur */
++ IOH_DEBUG("ioc_handle_notify waiting for interrupt event...\n");
++ wait_event_interruptible(*event,
++ ioh_1588_devp->event_flags[eventnum] == 1);
++ IOH_DEBUG("ioc_handle_notify got interrupt event...\n");
++
++ /* copy global data retreived from interrupt handler */
++ (void)memcpy((void *)&buf, (const void *)param_addr, bytes_ret);
++
++ /* reset global data to 0 */
++ (void)memset((void *)param_addr, 0, bytes_ret);
++
++ ioh_1588_devp->event_flags[eventnum] = 0;
++
++ return 0;
++}
++
++/* Handles all CLEAR NOTIFY IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_clr_notify (unsigned long cmd, char *buf)
++ * @brief Handles all CLEAR NOTIFY IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf unused
++ * @retval int
++ * - 0 on success
++ * - -EINVAL for unsupported IOCTL
++ * <hr>
++ */
++static int ioc_handle_clr_notify(unsigned long cmd, char *buf)
++{
++ unsigned int eventnum = 0;
++
++ /*
++ * request to release a notify thread that is waiting
++ * on a 1588 interrupt event
++ */
++ if (cmd == IOCTL_1588_TARG_TIME_CLR_NOTIFY) {
++ IOH_DEBUG
++ ("ioc_handle_clr_notify cmd=\
++ IOCTL_1588_TARG_TIME_CLR_NOTIFY\n");
++ eventnum = TARG_TIME_EVENT_NUM;
++ } else if (cmd == IOCTL_1588_AUX_TIME_CLR_NOTIFY) {
++ IOH_DEBUG
++ ("ioc_handle_clr_notify cmd=\
++ IOCTL_1588_AUX_TIME_CLR_NOTIFY\n");
++ eventnum = AUX_TIME_EVENT_NUM;
++ } else if (cmd == IOCTL_1588_PULSE_PER_SEC_CLR_NOTIFY) {
++ IOH_DEBUG
++ ("ioc_handle_clr_notify cmd=\
++ IOCTL_1588_PULSE_PER_SEC_CLR_NOTIFY\n");
++ eventnum = PPS_EVENT_NUM;
++ } else if (cmd == IOCTL_1588_AUX_TARG_TIME_CLR_NOTIFY) {
++ IOH_DEBUG
++ ("ioc_handle_clr_notify cmd=\
++ IOCTL_1588_AUX_TARG_TIME_CLR_NOTIFY\n");
++ IOH_LOG(KERN_ERR, "ioc_handle_clr_notify returning -EINVAL\n");
++ return -EINVAL;
++ }
++
++ ioh_1588_devp->event_flags[eventnum] = 1;
++
++ IOH_DEBUG("ioc_handle_clr_notify waking up blocking notify call...\n");
++ wake_up_interruptible(&ioh_1588_devp->notify_evt[eventnum]);
++ return 0;
++}
++
++/* Handles reset and channel reset IOCTLs */
++
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_reset (unsigned long cmd, char *buf)
++ * @brief Handles reset and channel reset IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf unused
++ * @retval int
++ * - 0 on success
++ * - -EINVAL when hardware reset fails
++ * <hr>
++ */
++static int ioc_handle_reset(unsigned long cmd, char *buf)
++{
++ int i = 0;
++ int ieee_mode;
++ unsigned char station[STATION_ADDR_LEN] = "00:00:00:00:00:00";
++
++ IOH_DEBUG("ioc_handle_reset: invoking ioh_1588_reset\n");
++
++ /*retrieve eth/CAN mode */
++ ieee_mode = ioh_1588_eth_can_get();
++
++ /*retrive station address */
++ ioh_1588_get_station_address(station);
++
++ /* reset the 1588 hardware */
++ if (ioh_1588_reset() != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioc_handle_reset: ioh_1588_reset failed\n");
++ return -EINVAL;
++ }
++ /* Anyway, now clear all the events */
++ for (i = 0; i < NUM_EVENTS; i++)
++ ioh_1588_devp->event_flags[i] = 0;
++ /*set ETH/CAN mode */
++ if (ieee_mode & IOH_IEEE1588_ETH)
++ ioh_1588_eth_enable();
++ if (ieee_mode & IOH_IEEE1588_CAN)
++ ioh_1588_can_enable();
++
++ /*set station address */
++ if (strcmp(station, "00:00:00:00:00:00") != 0) {
++ if (ioh_1588_set_station_address(station) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_reset: could not set station \
++ address\n");
++ }
++ }
++
++ IOH_DEBUG("ioc_handle_reset: returning 0\n");
++ return 0;
++}
++
++/* Handles reset statistics IOCTL */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_stats_reset (unsigned long cmd, char *buf)
++ * @brief Handles reset statistics IOCTLs
++ * @param cmd unused
++ * @param buf unused
++ * @retval int
++ * - 0 on success
++ * <hr>
++ */
++static int ioc_handle_stats_reset(unsigned long cmd, char *buf)
++{
++
++ IOH_DEBUG("ioc_handle_stats_reset: invoking ioh_1588_stats_reset\n");
++ ioh_1588_stats_reset();
++ IOH_DEBUG("ioc_handle_stats_reset: returning 0\n");
++ return 0;
++}
++
++/* Handles get statistics IOCTL */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_stats (unsigned long cmd, char *buf)
++ * @brief Handles get statistics IOCTL
++ * @param cmd [IN] the IOCTL command
++ * @param buf [OUT] reference to statistics retrieved
++ * @retval int
++ * - 0 on success
++ * <hr>
++ */
++static int ioc_handle_stats(unsigned long cmd, char *buf)
++{
++ IOH_DEBUG("ioc_handle_stats: invoking ioh_ioh_1588_stats_get\n");
++ if (ioh_1588_stats_get((struct ioh1588Stats *) buf) != \
++ IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_stats_get failed\n");
++ return -EINVAL;
++ }
++ IOH_DEBUG("ioc_handle_statst: returning 0\n");
++ return 0;
++}
++
++/* Handles show all IOCTL */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_show (unsigned long cmd, char *buf)
++ * @brief Handles show all IOCTL
++ * @param cmd unused
++ * @param buf unused
++ * @retval int
++ * - 0 on success
++ * - -EINVAL when @ref ioh_1588_show fails
++ * <hr>
++ */
++static int ioc_handle_show(unsigned long cmd, char *buf)
++{
++ IOH_DEBUG("ioc_handle_show: invoking ioh_1588_show\n");
++ if (ioh_1588_show() != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: ioh_1588_show failed\n");
++ return -EINVAL;
++ }
++ IOH_DEBUG("ioc_handle_show: returning 0\n");
++ return 0;
++}
++
++/* Handles all interrupt enable IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_int_enable (unsigned long cmd, char *buf)
++ * @brief Handles all interrupt enable IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [IN] the reference to auxiliary mode
++ * @retval int
++ * - 0 on success
++ * - -EINVAL failed to enable interrupt
++ * <hr>
++ */
++static int ioc_handle_int_enable(unsigned long cmd, char *buf)
++{
++ int ret = 0;
++
++ if (IOCTL_1588_TARG_TIME_INTRPT_ENABLE == cmd) {
++ IOH_DEBUG
++ ("ioc_handle_int_enable cmd=\
++ IOCTL_1588_TARG_TIME_INTRPT_ENABLE \
++ invoking \
++ ioh_1588_target_time_interrupt_enable\n");
++ if (ioh_1588_target_time_interrupt_enable(target_time_callback)
++ != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \
++ ioh_1588_target_time_interrupt_enable \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else if (IOCTL_1588_AUX_TIME_INTRPT_ENABLE == cmd) {
++ enum ioh1588AuxMode aux_mode;
++ IOH_DEBUG
++ ("ioc_handle_int_enable cmd=\
++ IOCTL_1588_AUX_TIME_INTRPT_ENABLE \
++ invoking ioh_1588_aux_time_interrupt_enable\n");
++
++ (void)memcpy((void *)&aux_mode, (const void *)buf,
++ sizeof(enum ioh1588AuxMode));
++
++ if (ioh_1588_aux_time_interrupt_enable
++ (aux_mode, auxiliary_time_callback) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \
++ ioh_1588_aux_time_interrupt_enable \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else if (IOCTL_1588_PULSE_PER_SEC_INTRPT_ENABLE == cmd) {
++ IOH_DEBUG
++ ("ioc_handle_int_enable cmd=\
++ IOCTL_1588_PULSE_PER_SEC_INTRPT_ENABLE \
++ invoking \
++ ioh_1588_pulse_per_sec_interrupt_enable\n");
++ if (ioh_1588_pulse_per_sec_interrupt_enable
++ (pulse_per_sec_callback)
++ != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \
++ ioh_1588_pps_interrupt_enable \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else { /* IOCTL_1588_AUX_TARG_TIME_INTRPT_ENABLE */
++
++ IOH_DEBUG
++ ("ioc_handle_int_enable cmd=\
++ OCTL_1588_AUX_TARG_TIME_INTRPT_ENABLE \
++ invoking \
++ ioh_1588_aux_target_time_interrupt_enable\n");
++ if (ioh_1588_aux_target_time_interrupt_enable((void *)NULL)
++ != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \
++ ioh_1588_aux_target_time_interrupt_enable \
++ failed\n");
++ ret = -EINVAL;
++ }
++ }
++ return ret;
++}
++
++/* Handles all interrupt disable IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_int_disable (unsigned long cmd, char *buf)
++ * @brief Handles all interrupt enable IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [IN] the reference to auxiliary mode
++ * @retval int
++ * - 0 on success
++ * - -EINVAL failed to disable interrupt
++ * <hr>
++ */
++static int ioc_handle_int_disable(unsigned long cmd, char *buf)
++{
++ int ret = 0;
++
++ if (IOCTL_1588_TARG_TIME_INTRPT_DISABLE == cmd) {
++ IOH_DEBUG
++ ("ioc_handle_int_disable cmd=\
++ IOCTL_1588_TARG_TIME_INTRPT_DISABLE \
++ invoking \
++ ioh_1588_target_time_interrupt_disable\n");
++ if (ioh_1588_target_time_interrupt_disable()
++ != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \
++ ioh_1588_target_time_interrupt_disable \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else if (IOCTL_1588_AUX_TIME_INTRPT_DISABLE == cmd) {
++ enum ioh1588AuxMode aux_mode;
++ IOH_DEBUG
++ ("ioc_handle_int_disable cmd=\
++ IOCTL_1588_AUX_TIME_INTRPT_DISABLE \
++ invoking \
++ ioh_1588_aux_time_interrupt_disable\n");
++
++ (void)memcpy((void *)&aux_mode, (const void *)buf,
++ sizeof(enum ioh1588AuxMode));
++
++ if (ioh_1588_aux_time_interrupt_disable(aux_mode)
++ != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \
++ ioh_1588_aux_time_interrupt_disable \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else if (IOCTL_1588_PULSE_PER_SEC_INTRPT_DISABLE == cmd) {
++ IOH_DEBUG
++ ("ioc_handle_int_disable cmd=\
++ IOCTL_1588_PULSE_PER_SEC_INTRPT_DISABLE \
++ invoking \
++ ioh_1588_pulse_per_sec_interrupt_disable\n");
++ if (ioh_1588_pulse_per_sec_interrupt_disable() !=
++ IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \
++ ioh_1588_pulse_per_sec_interrupt_disable \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else { /* IOCTL_1588_AUX_TARG_TIME_INTRPT_DISABLE */
++
++ IOH_DEBUG
++ ("ioc_handle_int_disable cmd=\
++ IOCTL_1588_AUX_TARG_TIME_INTRPT_DISABLE \
++ invoking \
++ ioh_1588_aux_target_time_interrupt_disable\n");
++ if (ioh_1588_aux_target_time_interrupt_disable() !=
++ IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \
++ ioh_1588_aux_target_time_interrupt_disable \
++ failed\n");
++ ret = -EINVAL;
++ }
++ }
++ return ret;
++}
++
++/* Handles port config set/get IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_port_config (unsigned long cmd, char *buf)
++ * @brief Handles port config set/get IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [IN] the port configuration
++ * @retval int
++ * - 0 on success
++ * - -EINVAL failed to set/get port configuration
++ * <hr>
++ */
++static int ioc_handle_port_config(unsigned long cmd, char *buf)
++{
++ struct ioh1588PortCfgIoctl *port_cfg_ioctl = \
++ (struct ioh1588PortCfgIoctl *) buf;
++
++ if (IOCTL_1588_PORT_CONFIG_SET == cmd) {
++ IOH_DEBUG
++ ("ioc_handle_port_config cmd = IOCTL_1588_PORT_CONFIG_SET \
++ invoking ioh_1588_ptp_port_config_set\n");
++
++ if (ioh_1588_ptp_port_config_set(port_cfg_ioctl->ptpPort,
++ port_cfg_ioctl->ptpPortMode) !=
++ IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_ptp_port_config_set \
++ failed\n");
++ return -EINVAL;
++ }
++ } else { /* IOCTL_1588_PORT_CONFIG_GET */
++
++ IOH_DEBUG
++ ("ioc_handle_port_config cmd = IOCTL_1588_PORT_CONFIG_GET \
++ invoking ioh_1588_ptp_port_config_get\n");
++ if (ioh_1588_ptp_port_config_get
++ (port_cfg_ioctl->ptpPort,
++ &port_cfg_ioctl->ptpPortMode) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_ptp_port_config_get \
++ failed\n");
++ return -EINVAL;
++ }
++ }
++ return 0;
++}
++
++/* Handles all POLL IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_poll (unsigned long cmd, char *buf)
++ * @brief Handles all poll IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [IN] the poll configuration
++ * @retval int
++ * - 0 on success
++ * - -EINVAL on failure
++ * <hr>
++ */
++static int ioc_handle_poll(unsigned long cmd, char *buf)
++{
++ int ret = 0;
++ struct ioh1588RxTxPollIoctl *poll_ioctl = \
++ (struct ioh1588RxTxPollIoctl *) buf;
++ struct ioh1588CANPollIoctl *can_poll_ioctl = \
++ (struct ioh1588CANPollIoctl *) buf;
++ struct ioh1588TimePollIoctl *time_poll_ioctl = \
++ (struct ioh1588TimePollIoctl *) buf;
++
++ if (IOCTL_1588_RX_POLL == cmd) {
++ IOH_DEBUG("ioc_handle_poll: cmd = IOCTL_1588_RX_POLL \
++ invoking ioh_1588_ptp_rx_poll\n");
++ ret = ioh_1588_ptp_rx_poll(poll_ioctl->ptpPort,
++ &poll_ioctl->ptpMsgData);
++ if ((ret != IOH_1588_SUCCESS) && \
++ (ret != IOH_1588_NOTIMESTAMP)) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_ptp_rx_poll \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else if (IOCTL_1588_TX_POLL == cmd) {
++ IOH_DEBUG("ioc_handle_poll: cmd = IOCTL_1588_TX_POLL \
++ invoking ioh_1588_ptp_tx_poll\n");
++ ret = ioh_1588_ptp_tx_poll(poll_ioctl->ptpPort,
++ &poll_ioctl->ptpMsgData);
++ if ((ret != IOH_1588_SUCCESS) && \
++ (ret != IOH_1588_NOTIMESTAMP)) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_ptp_tx_poll \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else if (IOCTL_1588_CAN_POLL == cmd) {
++ IOH_DEBUG("ioc_handle_poll: cmd = IOCTL_1588_CAN_POLL \
++ invoking ioh_1588_ptp_can_poll\n");
++ ret = ioh_1588_ptp_can_poll(can_poll_ioctl->ptpPort,
++ &can_poll_ioctl->ptpTimeStamp);
++ if ((ret != IOH_1588_SUCCESS) && \
++ (ret != IOH_1588_NOTIMESTAMP)) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_ptp_can_poll \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else if (IOCTL_1588_TARG_TIME_POLL == cmd) {
++ IOH_DEBUG("ioc_handle_poll: cmd = IOCTL_1588_TARG_TIME_POLL "
++ "invoking ioh_1588_target_time_poll\n");
++ if (ioh_1588_target_time_poll(&time_poll_ioctl->pollFlag,
++ &time_poll_ioctl->timeVal) !=
++ IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_target_time_poll \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else if (IOCTL_1588_AUX_TIME_POLL == cmd) {
++ IOH_DEBUG("ioc_handle_poll: cmd = IOCTL_1588_AUX_TIME_POLL "
++ "invoking ioh_1588_aux_time_poll\n");
++ if (ioh_1588_aux_time_poll(time_poll_ioctl->auxMode,
++ &time_poll_ioctl->pollFlag,
++ &time_poll_ioctl->timeVal)
++ != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_aux_time_poll \
++ failed\n");
++ ret = -EINVAL;
++ }
++ } else { /* IOCTL_1588_AUX_TARG_TIME_POLL */
++
++ IOH_DEBUG
++ ("ioc_handle_poll: cmd = IOCTL_1588_AUX_TARG_TIME_POLL "
++ "invoking ioh_1588_aux_target_time_poll\n");
++ if (ioh_1588_aux_target_time_poll
++ (&time_poll_ioctl->pollFlag,
++ &time_poll_ioctl->timeVal) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_aux_target_time_poll \
++ failed\n");
++ ret = -EINVAL;
++ }
++ }
++ if ((unsigned long)ret == IOH_1588_NOTIMESTAMP)
++ ret = 0;
++ return ret;
++}
++
++/* Handles all Time Set IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_time_set (unsigned long cmd, char *buf)
++ * @brief Handles all Time Set IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [IN] the time value
++ * @retval int
++ * - 0 on success
++ * - -EINVAL on failure
++ * <hr>
++ */
++static int ioc_handle_time_set(unsigned long cmd, char *buf)
++{
++ struct ioh1588TimeValue time_value;
++
++ (void)memcpy((void *)&time_value, (const void *)buf,
++ sizeof(struct ioh1588TimeValue));
++
++ if (IOCTL_1588_SYS_TIME_SET == cmd) {
++ IOH_DEBUG("ioc_handle_time_set cmd=IOCTL_1588_SYS_TIME_SET \
++ invoking ioh_1588_system_time_set\n");
++ if (ioh_1588_system_time_set(time_value) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_system_time_set \
++ failed\n");
++ return -EINVAL;
++ }
++ } else if (IOCTL_1588_TARG_TIME_SET == cmd) {
++ IOH_DEBUG("ioc_handle_time_set cmd=IOCTL_1588_TARG_TIME_SET \
++ invoking ioh_1588_target_time_set\n");
++ if (ioh_1588_target_time_set(time_value) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_target_time_set \
++ failed\n");
++ return -EINVAL;
++ }
++ } else { /* IOCTL_1588_AUX_TARG_TIME_SET */
++
++ IOH_DEBUG
++ ("ioc_handle_time_set cmd=IOCTL_1588_AUX_TARG_TIME_SET \
++ invoking ioh_1588_aux_target_time_set\n");
++ if (ioh_1588_aux_target_time_set(time_value) !=
++ IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_aux_target_time_set \
++ failed\n");
++ return -EINVAL;
++ }
++ }
++ return 0;
++}
++
++/* Handles all Time Get IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_time_get (unsigned long cmd, char *buf)
++ * @brief Handles all Time Get IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [OUT] the time value
++ * @retval int
++ * - 0 on success
++ * - -EINVAL on failure
++ * <hr>
++ */
++static int ioc_handle_time_get(unsigned long cmd, char *buf)
++{
++ struct ioh1588TimeValue time_value;
++
++ if (IOCTL_1588_SYS_TIME_GET == cmd) {
++ IOH_DEBUG("ioc_handle_time_get cmd=IOCTL_1588_SYS_TIME_GET \
++ invoking ioh_1588_system_time_get\n");
++ if (ioh_1588_system_time_get(&time_value) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_system_time_get \
++ failed\n");
++ return -EINVAL;
++ }
++ } else if (IOCTL_1588_TARG_TIME_GET == cmd) {
++ IOH_DEBUG("ioc_handle_time_get cmd=IOCTL_1588_TARG_TIME_GET \
++ invoking ioh_1588_target_time_get\n");
++ if (ioh_1588_target_time_get(&time_value) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_target_time_get \
++ failed\n");
++ return -EINVAL;
++ }
++ } else { /* IOCTL_1588_AUX_TARG_TIME_GET */
++
++ IOH_DEBUG
++ ("ioc_handle_time_get cmd=IOCTL_1588_AUX_TARG_TIME_GET \
++ invoking ioh_1588_aux_target_time_get\n");
++ if (ioh_1588_aux_target_time_get(&time_value)) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_aux_target_time_set \
++ failed\n");
++ return -EINVAL;
++ }
++ }
++
++ (void)memcpy((void *)buf, (const void *)&time_value,
++ sizeof(struct ioh1588TimeValue));
++ return 0;
++}
++
++/* Handles tick rate get/set IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_tick_rate (unsigned long cmd, char *buf)
++ * @brief Handles tick rate get/set IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [OUT] the tick rate
++ * @retval int
++ * - 0 on success
++ * - -EINVAL on failure
++ * <hr>
++ */
++static int ioc_handle_tick_rate(unsigned long cmd, char *buf)
++{
++ unsigned long val;
++
++ if (IOCTL_1588_TICK_RATE_GET == cmd) {
++ IOH_DEBUG("ioc_handle_tick_rate cmd =IOCTL_1588_TICK_RATE_GET \
++ invoking ioh_1588_tick_rate_get\n");
++ if (ioh_1588_tick_rate_get(&val) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_tick_rate_get \
++ failed\n");
++ return -EINVAL;
++ }
++
++ (void)memcpy((void *)buf, (const void *)&val, sizeof val);
++ } else { /* (cmd == IOCTL_1588_TICK_RATE_SET) */
++
++ IOH_DEBUG("ioc_handle_tick_rate cmd =IOCTL_1588_TICK_RATE_SET \
++ invoking ioh_1588_tick_rate_set\n");
++ (void)memcpy((void *)&val, (const void *)buf, sizeof val);
++
++ if (ioh_1588_tick_rate_set(val) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_tick_rate_set \
++ failed\n");
++ return -EINVAL;
++ }
++ }
++ return 0;
++}
++
++/* Handles pps time get/set IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_pps_reqt (unsigned long cmd, char *buf)
++ * @brief Handles pps time get/set IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [INOUT] the pulse per second value
++ * @retval int
++ * - 0 on success
++ * - -EINVAL on failure
++ * <hr>
++ */
++static int ioc_handle_pps_reqt(unsigned long cmd, char *buf)
++{
++ unsigned long val;
++
++ if (IOCTL_1588_PULSE_PER_SEC_TIME_SET == cmd) {
++ IOH_DEBUG
++ ("ioc_handle_pps_reqt cmd=\
++ IOCTL_1588_PULSE_PER_SEC_TIME_SET \
++ invoking ioh_1588_pulse_per_sec_time_set\n");
++ (void)memcpy((void *)&val, (const void *)buf, sizeof val);
++ if (ioh_1588_pulse_per_sec_time_set(val) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \
++ ioh_1588_pulse_per_sec_time_set \
++ failed\n");
++ return -EINVAL;
++ }
++ } else { /* IOCTL_1588_PULSE_PER_SEC_TIME_GET */
++
++ IOH_DEBUG
++ ("ioc_handle_pps_reqt cmd=\
++ IOCTL_1588_PULSE_PER_SEC_TIME_GET \
++ invoking ioh_1588_pulse_per_sec_time_get\n");
++ if (ioh_1588_pulse_per_sec_time_get(&val) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \
++ ioh_1588_pulse_per_sec_time_get failed\n");
++ return -EINVAL;
++ }
++ (void)memcpy((void *)buf, (const void *)&val, sizeof val);
++ }
++ return 0;
++}
++
++/* Handles ptp version get/set IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_version_reqt (unsigned long cmd, char *buf)
++ * @brief Handles ptp version get/set IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [INOUT]the ptp version
++ * @retval int
++ * - 0 on success
++ * - -EINVAL on failure
++ * <hr>
++ */
++static int ioc_handle_version_reqt(unsigned long cmd, char *buf)
++{
++ struct ioh1588VersionIoctl *version_ioctl = \
++ (struct ioh1588VersionIoctl *) buf;
++
++ if (IOCTL_1588_PORT_VERSION_SET == cmd) {
++ IOH_DEBUG
++ ("ioc_handle_version_reqt cmd=IOCTL_1588_PORT_VERSION_SET \
++ invoking ioh_1588_ptp_version_set\n");
++ if (ioh_1588_ptp_version_set
++ (version_ioctl->ptpPort,
++ version_ioctl->ptpVersion) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_ptp_version_set \
++ failed\n");
++ return -EINVAL;
++ }
++ } else { /* IOCTL_1588_PORT_VERSION_GET */
++
++ IOH_DEBUG
++ ("ioc_handle_version_reqt cmd=IOCTL_1588_PORT_VERSION_GET \
++ invoking ioh_1588_ptp_version_get\n");
++ if (ioh_1588_ptp_version_get
++ (version_ioctl->ptpPort,
++ &version_ioctl->ptpVersion) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: ioh_1588_ptp_version_get \
++ failed\n");
++ return -EINVAL;
++ }
++ }
++ return 0;
++}
++
++/* Handles ptp operation mode get/set IOCTLs */
++/*! @ingroup IEEE_1588_UtilitiesAPI
++ * @fn ioc_handle_op_mode_reqt (unsigned long cmd, char *buf)
++ * @brief Handles ptp operation mode get/set IOCTLs
++ * @param cmd [IN] the IOCTL command
++ * @param buf [INOUT]the ptp operation mode
++ * @retval int
++ * - 0 on success
++ * - -EINVAL on failure
++ * <hr>
++ */
++static int ioc_handle_op_mode_reqt(unsigned long cmd, char *buf)
++{
++ struct ioh1588OperationModeIoctl *opmode_ioctl =
++ (struct ioh1588OperationModeIoctl *) buf;
++
++ if (IOCTL_1588_PORT_OPERATION_MODE_SET == cmd) {
++ IOH_DEBUG
++ ("ioc_handle_op_mode_reqt cmd=\
++ IOCTL_1588_PORT_OPERATION_MODE_SET \
++ invoking ioh_1588_ptp_operation_mode_set\n");
++ if (ioh_1588_ptp_operation_mode_set
++ (opmode_ioctl->ptpPort,
++ opmode_ioctl->ptpOpMode) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: \
++ ioh_1588_ptp_operation_mode_set failed\n");
++ return -EINVAL;
++ }
++ } else { /* IOCTL_1588_PORT_OPERATION_MODE_GET */
++
++ IOH_DEBUG
++ ("ioc_handle_op_mode_reqt cmd=\
++ IOCTL_1588_PORT_OPERATION_MODE_GET \
++ invoking ioh_1588_ptp_operation_mode_get\n");
++ if (ioh_1588_ptp_operation_mode_get
++ (opmode_ioctl->ptpPort,
++ &opmode_ioctl->ptpOpMode) != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_ioctl: \
++ ioh_1588_ptp_operation_mode_get failed\n");
++ return -EINVAL;
++ }
++ }
++ return 0;
++}
++
++/*! @ingroup InterfaceLayerNotifyRoutines
++ * @fn irqreturn_t ioh_1588_isr(int irq, void *p_data)
++ * @brief This function is the driver interrupt service routine.
++ *
++ * @param irq [IN] interrupt number
++ * @param p_data caller data
++ *
++ * @retval irqreturn_t
++ * - IRQ_HANDLED => interrupt handled,
++ * - IRQ_NONE => this device did not interrupt
++ */
++irqreturn_t ioh_1588_isr(int irq, void *p_data)
++{
++ unsigned long pending = 0;
++
++ (void)ioh_1588_interrupt_pending(&pending);
++ if (!pending) {
++ IOH_DEBUG("ioh_1588_isr: no pending interrupt\n");
++ return IRQ_NONE;
++ }
++
++ if (ioh_1588_handler() != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR, "ioh_1588_isr: ioh_1588_handler failed\n");
++ return IRQ_NONE;
++ }
++
++ return IRQ_HANDLED;
++}
++
++/*! @ingroup InterfaceLayerNotifyRoutines
++ * @fn void target_time_callback(struct ioh1588TimeValue tgt_time)
++ * @brief The callback function that is called from the HAL
++ * when the target time expired interrupt occurs
++ *
++ * @param tgt_time target time register timestamp
++ *
++ * @retval None
++ */
++void target_time_callback(struct ioh1588TimeValue tgt_time)
++{
++ /*
++ * copy the target time value to the global value to be read by the
++ * notify ioctl
++ */
++ (void)memcpy((void *)&ioh_1588_target_time, (const void *)&tgt_time,
++ sizeof(struct ioh1588TimeValue));
++
++ ioh_1588_devp->event_flags[TARG_TIME_EVENT_NUM] = 1;
++
++ IOH_DEBUG("target_time_callback: signalling the notify ioctl \
++ that the target time has expired\n");
++ /* signal the notify ioctl that the target time has expired */
++ wake_up_interruptible(&ioh_1588_devp->notify_evt[TARG_TIME_EVENT_NUM]);
++}
++
++/*! @ingroup InterfaceLayerNotifyRoutines
++ * @fn void auxiliary_time_callback(enum ioh1588AuxMode aux_mode,
++ * struct ioh1588TimeValue aux_time)
++ * @brief The callback function that is called from the HAL
++ * when an aux time interrupt has occurred
++ *
++ * @param aux_mode master, slave, or any
++ * @param aux_time aux time register timestamp
++ *
++ * @return None
++ */
++void auxiliary_time_callback(enum ioh1588AuxMode aux_mode, \
++ struct ioh1588TimeValue aux_time)
++{
++ /*
++ * copy the aux time value and aux mode to the global value
++ * to be read by the notify ioctl
++ */
++
++ ioh_1588_aux_time.auxMode = aux_mode;
++ (void)memcpy((void *)&ioh_1588_aux_time.auxTime,
++ (const void *)&aux_time, \
++ sizeof(struct ioh1588AuxTimeIoctl));
++
++ ioh_1588_devp->event_flags[AUX_TIME_EVENT_NUM] = 1;
++
++ IOH_DEBUG("auxiliary_time_callback: signalling the notify ioctl \
++ that the auxiliary time stamp has been set\n");
++
++ /*
++ * signal the notify ioctl that the aux timestamp has been set
++ */
++ wake_up_interruptible(&ioh_1588_devp->notify_evt[AUX_TIME_EVENT_NUM]);
++}
++
++/*! @ingroup InterfaceLayerNotifyRoutines
++ * @fn void pulse_per_sec_callback(unsigned long pps)
++ * @brief This is a callback function that will be called from the HAL
++ * when the pulse per second time has expired which generates an
++ * interrupt
++ *
++ * @param pps pulse per second register timestamp
++ *
++ * @retval None
++ */
++void pulse_per_sec_callback(unsigned long pps)
++{
++ ioh_1588_pps_time = pps;
++
++ ioh_1588_devp->event_flags[PPS_EVENT_NUM] = 1;
++
++ IOH_DEBUG("pulse_per_sec_callback: signalling the notify ioctl \
++ that the pulse per second time has expired\n");
++ /* signal the notify ioctl that the pulse per second time has expired */
++
++ wake_up_interruptible(&ioh_1588_devp->notify_evt[PPS_EVENT_NUM]);
++}
+diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.h topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.h
+--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.h 1970-01-01 09:00:00.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.h 2010-03-09 10:22:48.000000000 +0900
+@@ -0,0 +1,702 @@
++ /*!
++ * @file ioh_1588_main.h
++ * @brief
++ * This file contains the declarations of IEEE_1588_InterfaceLayer APIs
++ * @version 0.92
++ * @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:
++ * modified to support Intel IOH GE IEEE 1588 hardware
++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
++ * All rights reserved.
++ * derived from
++ * IEEE 1588 Time Synchronization Driver for Intel EP80579
++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ * All rights reserved.
++ *
++ */
++
++#ifndef IOH_1588_MAIN_H
++#define IOH_1588_MAIN_H
++
++#ifdef __GNUC__
++#define UNUSED __attribute__ ((unused))
++#define UNUSED_ARG(x)
++#else
++#define UNUSED
++#define UNUSED_ARG(x) (void) x
++#endif
++
++#include <linux/ioctl.h>
++
++#define TRUE 1
++#define FALSE 0
++
++/*! @defgroup IEEE1588*/
++
++/*! @defgroup IEEE_1588_Global
++ * @ingroup IEEE1588
++ * @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 IEEE_1588_PCILayer
++ * @ingroup IEEE1588
++ * @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 IEEE_1588_InterfaceLayer
++ * @ingroup IEEE1588
++ * @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 IEEE_1588_HALLayer
++ * @ingroup IEEE1588
++ * @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 IEEE_1588_Utilities
++ * @ingroup IEEE1588
++ * @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 IEEE_1588_PCILayerAPI
++ * @ingroup IEEE_1588_PCILayer
++ * @brief This group contains the API(functions) used as the PCI
++ * interface between the Kernel subsystem and the module.
++ *<hr>
++ **/
++
++/*! @defgroup IEEE_1588_PCILayerFacilitators
++ * @ingroup IEEE_1588_PCILayer
++ * @brief This group contains the data structures used by the PCI
++ * Layer APIs for their functionalities.
++ * <hr>
++ **/
++
++/*! @defgroup IEEE_1588_InterfaceLayerAPI
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @brief This group contains the API(functions) used as the Driver
++ * interface between the Kernel subsystem and the module.
++ * <hr>
++ **/
++
++/*! @defgroup IEEE_1588_InterfaceLayerFacilitators
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @brief This group contains the data structures used by the Driver
++ * interface APIs for their functionalities.
++ * <hr>
++ **/
++
++/*! @defgroup IEEE_1588_HALLayerAPI
++ * @ingroup IEEE_1588_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 IEEE_1588_UtilitiesAPI
++ * @ingroup IEEE_1588_Utilities
++ * @brief This group contains the APIs(functions) used by other
++ * functions
++ * in their operations.
++ * <hr>
++ **/
++
++/* 1588 module ioctl command codes */
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOC_1588_BASE
++ * @brief The unique one byte data used to define
++ * the IOCTL commands
++ */
++#define IOC_1588_BASE 0x88
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PORT_CONFIG_SET
++ * @brief Set the IEEE 1588 Ethernet port to Mater/Slave/All mode
++ */
++#define IOCTL_1588_PORT_CONFIG_SET \
++ _IOW(IOC_1588_BASE, 0, struct ioh1588PortCfgIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PORT_CONFIG_GET
++ * @brief Get the IEEE 1588 Ethernet port Configuration mode
++ */
++#define IOCTL_1588_PORT_CONFIG_GET \
++ _IOWR(IOC_1588_BASE, 1, struct ioh1588PortCfgIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_RX_POLL
++ * @brief Poll for receive timestamp captured on the IEEE 1588 ethernet
++ * channel
++ */
++#define IOCTL_1588_RX_POLL _IOWR(IOC_1588_BASE, 2, struct ioh1588RxTxPollIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_TX_POLL
++ * @brief Poll for transmit timestamp captured on the IEEE 1588 ethernet
++ * channel
++ */
++#define IOCTL_1588_TX_POLL _IOWR(IOC_1588_BASE, 3, struct ioh1588RxTxPollIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_CAN_POLL
++ * @brief Poll for timestamp captured on the IEEE 1588 CAN channel
++ */
++#define IOCTL_1588_CAN_POLL _IOWR(IOC_1588_BASE, 4, struct ioh1588CANPollIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_SYS_TIME_GET
++ * @brief Get the IEEE 1588 system time from the module
++ */
++#define IOCTL_1588_SYS_TIME_GET _IOR(IOC_1588_BASE, 5, struct ioh1588TimeValue)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_SYS_TIME_SET
++ * @brief Set the IEEE 1588 system time on the module
++ */
++#define IOCTL_1588_SYS_TIME_SET _IOW(IOC_1588_BASE, 6, struct ioh1588TimeValue)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_TICK_RATE_SET
++ * @brief Set the frequency scaling value used on IEEE 1588 module
++ */
++#define IOCTL_1588_TICK_RATE_SET _IOW(IOC_1588_BASE, 7, unsigned long)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_TICK_RATE_GET
++ * @brief Get the frequency scaling value used on IEEE 1588 module
++ */
++#define IOCTL_1588_TICK_RATE_GET _IOR(IOC_1588_BASE, 8, unsigned long)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_TARG_TIME_INTRPT_ENABLE
++ * @brief Enable the target time reached/exceeded interrupt on IEEE 1588 module
++ */
++#define IOCTL_1588_TARG_TIME_INTRPT_ENABLE _IO(IOC_1588_BASE, 9)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_TARG_TIME_INTRPT_DISABLE
++ * @brief Disable the target time reached/exceeded interrupt on IEEE 1588 module
++ */
++#define IOCTL_1588_TARG_TIME_INTRPT_DISABLE _IO(IOC_1588_BASE, 10)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_TARG_TIME_POLL
++ * @brief Poll for the target time reached/exceeded condition on IEEE 1588
++ * module
++ */
++#define IOCTL_1588_TARG_TIME_POLL \
++ _IOR(IOC_1588_BASE, 11, struct ioh1588TimePollIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_TARG_TIME_SET
++ * @brief Set the target time to match on IEEE 1588 module
++ */
++#define IOCTL_1588_TARG_TIME_SET \
++ _IOW(IOC_1588_BASE, 12, struct ioh1588TimeValue)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_TARG_TIME_GET
++ * @brief Get the target time currently set on IEEE 1588 module
++ */
++#define IOCTL_1588_TARG_TIME_GET \
++ _IOR(IOC_1588_BASE, 13, struct ioh1588TimeValue)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TIME_INTRPT_ENABLE
++ * @brief Enable the auxiliary time captured interrupt on IEEE 1588 module
++ */
++#define IOCTL_1588_AUX_TIME_INTRPT_ENABLE \
++ _IOW(IOC_1588_BASE, 14, enum ioh1588AuxMode)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TIME_INTRPT_DISABLE
++ * @brief Disable the auxiliary time captured interrupt on IEEE 1588 module
++ */
++#define IOCTL_1588_AUX_TIME_INTRPT_DISABLE \
++ _IOW(IOC_1588_BASE, 15, enum ioh1588AuxMode)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TIME_POLL
++ * @brief Poll for the auxiliary time captured on IEEE 1588 module
++ */
++#define IOCTL_1588_AUX_TIME_POLL \
++ _IOWR(IOC_1588_BASE, 16, struct ioh1588TimePollIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_RESET
++ * @brief Reset the IEEE 1588 module
++ */
++#define IOCTL_1588_RESET _IO(IOC_1588_BASE, 17)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_CHNL_RESET
++ * @brief Reset the IEEE 1588 channel
++ */
++#define IOCTL_1588_CHNL_RESET _IOW(IOC_1588_BASE, 18, enum ioh1588PTPPort)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_STATS_GET
++ * @brief Get the timestamp captured counters from the IEEE 1588 module
++ */
++#define IOCTL_1588_STATS_GET _IOR(IOC_1588_BASE, 19, struct ioh1588Stats)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_STATS_RESET
++ * @brief Reset the timestamp captured counters maintained for IEEE 1588 module
++ */
++#define IOCTL_1588_STATS_RESET _IO(IOC_1588_BASE, 20)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_SHOW_ALL
++ * @brief Display the register contents of IEEE 1588 module
++ */
++#define IOCTL_1588_SHOW_ALL _IO(IOC_1588_BASE, 21)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TARG_TIME_INTRPT_ENABLE
++ * @brief Enable Auxiliary target time reached interrupt - not supported
++ */
++#define IOCTL_1588_AUX_TARG_TIME_INTRPT_ENABLE _IO(IOC_1588_BASE, 22)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TARG_TIME_INTRPT_DISABLE
++ * @brief Disable Auxiliary target time reached interrupt - not supported
++ */
++#define IOCTL_1588_AUX_TARG_TIME_INTRPT_DISABLE _IO(IOC_1588_BASE, 23)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TARG_TIME_POLL
++ * @brief Poll for Auxiliary target time captured - not supported
++ */
++#define IOCTL_1588_AUX_TARG_TIME_POLL \
++ _IOR(IOC_1588_BASE, 24, struct ioh1588TimePollIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TARG_TIME_SET
++ * @brief Set Auxiliary target time - not supported
++ */
++#define IOCTL_1588_AUX_TARG_TIME_SET \
++ _IOW(IOC_1588_BASE, 25, struct ioh1588TimeValue)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TARG_TIME_GET
++ * @brief Get Auxiliary target time currently set - not supported
++ */
++#define IOCTL_1588_AUX_TARG_TIME_GET \
++ _IOR(IOC_1588_BASE, 26, struct ioh1588TimeValue)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PULSE_PER_SEC_INTRPT_ENABLE
++ * @brief Enable Pulse per second match interrupt
++ */
++#define IOCTL_1588_PULSE_PER_SEC_INTRPT_ENABLE _IO(IOC_1588_BASE, 27)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PULSE_PER_SEC_INTRPT_DISABLE
++ * @brief Disable Pulse per second match interrupt
++ */
++#define IOCTL_1588_PULSE_PER_SEC_INTRPT_DISABLE _IO(IOC_1588_BASE, 28)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_TARG_TIME_NOTIFY
++ * @brief Block till a target time reached interrupt occurs
++ */
++#define IOCTL_1588_TARG_TIME_NOTIFY \
++ _IOR(IOC_1588_BASE, 29, struct ioh1588TimeValue)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TIME_NOTIFY
++ * @brief Block till an auxiliary time captured interrupt occurs
++ */
++#define IOCTL_1588_AUX_TIME_NOTIFY \
++ _IOR(IOC_1588_BASE, 30, struct ioh1588AuxTimeIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TARG_TIME_NOTIFY
++ * @brief Block till an auxiliary target time reached interrupt occurs - not
++ * supported
++ */
++#define IOCTL_1588_AUX_TARG_TIME_NOTIFY \
++ _IOR(IOC_1588_BASE, 31, struct ioh1588TimeValue)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PULSE_PER_SEC_NOTIFY
++ * @brief Block till a pulse per second match interrupt occurs
++ */
++#define IOCTL_1588_PULSE_PER_SEC_NOTIFY _IOR(IOC_1588_BASE, 32, unsigned long)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_TARG_TIME_CLR_NOTIFY
++ * @brief Unblock a process waiting on target time reached interrupt
++ */
++#define IOCTL_1588_TARG_TIME_CLR_NOTIFY _IO(IOC_1588_BASE, 33)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TIME_CLR_NOTIFY
++ * @brief Unblock a process waiting on auxiliary time captured interrupt
++ */
++#define IOCTL_1588_AUX_TIME_CLR_NOTIFY _IO(IOC_1588_BASE, 34)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_AUX_TARG_TIME_CLR_NOTIFY
++ * @brief Unblock a process waiting on an auxiliary target time reached
++ * interrupt - not supported
++ */
++#define IOCTL_1588_AUX_TARG_TIME_CLR_NOTIFY _IO(IOC_1588_BASE, 35)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PULSE_PER_SEC_CLR_NOTIFY
++ * @brief Unblock a process waiting on a pulse per second match interrupt
++ */
++#define IOCTL_1588_PULSE_PER_SEC_CLR_NOTIFY _IO(IOC_1588_BASE, 36)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PULSE_PER_SEC_TIME_GET
++ * @brief Get the currently specified pulse per second match time
++ */
++#define IOCTL_1588_PULSE_PER_SEC_TIME_GET _IOR(IOC_1588_BASE, 37, unsigned long)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PULSE_PER_SEC_TIME_SET
++ * @brief Specify the pulse per second match time
++ */
++#define IOCTL_1588_PULSE_PER_SEC_TIME_SET _IOW(IOC_1588_BASE, 38, unsigned long)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PORT_VERSION_SET
++ * @brief Set the PTP version to be used on the given PTP channel
++ */
++#define IOCTL_1588_PORT_VERSION_SET \
++ _IOW(IOC_1588_BASE, 39, struct ioh1588VersionIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PORT_VERSION_GET
++ * @brief Get the PTP version used on the given PTP channel
++ */
++#define IOCTL_1588_PORT_VERSION_GET \
++ _IOWR(IOC_1588_BASE, 40, struct ioh1588VersionIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PORT_OPERATION_MODE_SET
++ * @brief Set the PTP messages that are matched by the module on the given PTP
++ * channel
++ */
++#define IOCTL_1588_PORT_OPERATION_MODE_SET \
++ _IOW(IOC_1588_BASE, 41, struct ioh1588OperationModeIoctl)
++
++/*! @ingroup IEEE_1588_InterfaceLayer
++ * @def IOCTL_1588_PORT_OPERATION_MODE_GET
++ * @brief Get the PTP messages that are currently matched by the module on given
++ * PTP channel
++ */
++#define IOCTL_1588_PORT_OPERATION_MODE_GET \
++ _IOWR(IOC_1588_BASE, 42, struct ioh1588OperationModeIoctl)
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @enum ioh1588PTPPort
++ * @brief IEEE 1588 PTP Communication Port(Channel)
++ */
++enum ioh1588PTPPort { /* ioh1588PTPPort */
++ IOH_1588_GBE_0_1588PTP_PORT, /**< PTP Communication Port on GBE-0 */
++ IOH_1588_CAN_0_1588PTP_PORT, /**< PTP Communication Port on CAN-0 */
++ IOH_1588_PORT_INVALID /**< Invalid PTP Communication Port */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @enum ioh1588PTPPortMode
++ * @brief PTP Port mode - Master or Slave or any
++ */
++enum ioh1588PTPPortMode { /* ioh1588PTPPortMode */
++ IOH_1588PTP_PORT_MASTER, /**< Master Mode */
++ IOH_1588PTP_PORT_SLAVE, /**< Slave Mode */
++ IOH_1588PTP_PORT_ANYMODE, /**< Timestamp all messages */
++ IOH_1588PTP_PORT_MODE_INVALID /**< Invalid PTP Port Mode */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588PortCfgIoctl
++ * @brief Struct to pass port config data for ioctl call
++ */
++struct ioh1588PortCfgIoctl { /* ioh1588PortCfgIoctl */
++ enum ioh1588PTPPort ptpPort; /**< IEEE 1588 PTP Communication Port */
++ enum ioh1588PTPPortMode ptpPortMode; /**< Master, Slave,
++ or Any mode */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @enum ioh1588PTPMsgType
++ * @brief PTP Messages types that can be detected on communication port
++ */
++enum ioh1588PTPMsgType { /* ioh1588PTPMsgType */
++ IOH_1588PTP_MSGTYPE_SYNC, /**< PTP Sync message sent by Master or
++ received by Slave */
++ IOH_1588PTP_MSGTYPE_DELAYREQ, /**< PTP Delay_Req message sent by Slave
++ or received by Master */
++ IOH_1588PTP_MSGTYPE_UNKNOWN /**< Other PTP and non-PTP message sent
++ or received by both Master
++ and/or Slave */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588TimeValue
++ * @brief Struct to hold 64 bit SystemTime and TimeStamp values
++ */
++struct ioh1588TimeValue { /* ioh1588TimeValue */
++ unsigned long timeValueLowWord; /**< Lower 32 bits of time value */
++ unsigned long timeValueHighWord; /**< Upper 32 bits of time value */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588Uuid
++ * @brief Struct to hold 48 bit UUID values captured in Sync or Delay_Req
++ * messages
++ */
++struct ioh1588Uuid{ /* ioh1588Uuid */
++ unsigned long uuidValueLowWord; /**< The lower 32 bits of UUID */
++ unsigned long uuidValueHighHalfword; /**< The upper 16 bits of UUID */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588PtpMsgData
++ * @brief Struct for data from the PTP message returned when TimeStamp
++ * available
++ */
++struct ioh1588PtpMsgData{ /* ioh1588PtpMsgData */
++ enum ioh1588PTPMsgType ptpMsgType; /**< PTP Messages type */
++ struct ioh1588TimeValue ptpTimeStamp; /**< 64 bit TimeStamp value from
++ PTP Message */
++ struct ioh1588Uuid ptpUuid; /**< 48 bit UUID value from the
++ PTP Message */
++ unsigned int ptpSequenceNumber; /**< 16 bit Sequence Number from PTP
++ Message */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588RxTxPollIoctl
++ * @brief Struct to pass PTP message data for ioctl call
++ */
++struct ioh1588RxTxPollIoctl{ /* ioh1588RxTxPollIoctl */
++ enum ioh1588PTPPort ptpPort; /**< IEEE 1588 PTP Communication Port */
++ struct ioh1588PtpMsgData ptpMsgData; /**< PTP message data */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588CANPollIoctl
++ * @brief Struct to pass CAN timestamp data for ioctl call
++ */
++struct ioh1588CANPollIoctl{ /* ioh1588CANPollIoctl */
++ enum ioh1588PTPPort ptpPort; /**< IEEE 1588 PTP Communication
++ Port */
++ struct ioh1588TimeValue ptpTimeStamp; /**< CAN PTP timestamp */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @enum ioh1588AuxMode
++ * @brief Master or Slave Auxiliary Time Stamp (Snap Shot)
++ */
++enum ioh1588AuxMode{ /* ioh1588AuxMode */
++ IOH_1588_AUXMODE_MASTER, /**< Auxiliary Master Mode */
++ IOH_1588_AUXMODE_SLAVE, /**< Auxiliary Slave Mode */
++ IOH_1588_AUXMODE_INVALID /**< Invalid Auxiliary Mode */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588TimePollIoctl
++ * @brief Struct to pass timestamp data for ioctl call
++ */
++struct ioh1588TimePollIoctl { /* ioh1588TimePollIoctl */
++ unsigned long pollFlag; /**< time event */
++ struct ioh1588TimeValue timeVal; /**< timestamp value */
++ enum ioh1588AuxMode auxMode; /**< Master or Slave mode */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588Stats
++ * @brief Provides the number of times timestamps are locked for rx and tx
++ * PTP
++ * messages. The counters are reinitialized when the module is
++ * reset.
++ */
++struct ioh1588Stats { /* ioh1588Stats */
++ unsigned long rxMsgs; /**< Count of timestamps for received PTP Msgs */
++ unsigned long txMsgs; /**< Count of timestamps for transmitted PTP
++ Msgs */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588AuxTimeIoctl
++ * @brief Struct to pass aux time data for ioctl call
++ */
++struct ioh1588AuxTimeIoctl { /* ioh1588AuxTimeIoctl */
++ enum ioh1588AuxMode auxMode; /**< aux mode: master or slave */
++ struct ioh1588TimeValue auxTime; /**< aux time snapshot */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @enum ioh1588PTPVersion
++ * @brief 1588 PTP version value that can be detected on communication
++ * port
++ */
++enum ioh1588PTPVersion { /* ioh1588PTPVersion */
++ IOH_1588PTP_VERSION_0, /**< support version 1 only */
++ IOH_1588PTP_VERSION_1, /**< support both version 1 and version
++ 2 */
++ IOH_1588PTP_VERSION_INVALID /**< Invalid version */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588VersionIoctl
++ * @brief Struct to pass timestamp data for ioctl call
++ */
++struct ioh1588VersionIoctl { /* ioh1588VersionIoctl */
++ enum ioh1588PTPPort ptpPort; /**< IEEE 1588 PTP Communication Port */
++ enum ioh1588PTPVersion ptpVersion; /**< version value */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @enum ioh1588VersionIoctl
++ * @brief 1588 PTP operation mode value that can be detected on
++ * communication port
++ */
++enum ioh1588PTPOperationMode { /* ioh1588PTPOperationMode */
++ IOH_1588PTP_OP_MODE_SYNC_DELAYREQ_MSGS,
++ /**< timestamp version 1 SYNC and DELAYED_REQ only */
++ IOH_1588PTP_OP_MODE_V1_ALL_MSGS,
++ /**< timestamp version 1 all messages */
++ IOH_1588PTP_OP_MODE_V1_V2_EVENT_MSGS,
++ /**< timestamp version 1 and 2 event messages only */
++ IOH_1588PTP_OP_MODE_V1_V2_ALL_MSGS,
++ /**< timestamp version 1 and 2 all messages */
++ IOH_1588PTP_OP_MODE_INVALID /**< Invalid mode */
++};
++
++/**
++ * @ingroup IEEE_1588_InterfaceLayer
++ * @struct ioh1588OperationModeIoctl
++ * @brief Struct to pass timestamp data for ioctl call
++ */
++struct ioh1588OperationModeIoctl { /* ioh1588OperationModeIoctl */
++ enum ioh1588PTPPort ptpPort; /**< IEEE 1588 PTP Communication
++ Port */
++ enum ioh1588PTPOperationMode ptpOpMode; /**< IEEE 1588 operation mode */
++};
++
++/**
++ * @ingroup IEEE_1588_Global
++ * @enum ioh_status
++ * @brief The status as returned from the HAL
++ */
++enum ioh_status { /* ioh_status */
++ IOH_1588_SUCCESS, /**< operation successful */
++ IOH_1588_INVALIDPARAM, /**< parameter passed is invalid */
++ IOH_1588_NOTIMESTAMP, /**< no time stamp available when
++ polled */
++ IOH_1588_INTERRUPTMODEINUSE, /**< while operating in interrupt mode,
++ polling not permitted */
++ IOH_1588_FAILED, /**< Internal error in driver */
++ IOH_1588_UNSUPPORTED, /**< Implementation does not support
++ this feature */
++};
++
++/* IEEE 1588 registers to save and restore on suspend/resume */
++
++/** @ingroup IEEE_1588_Global
++ * @struct ioh_1588_regs_set
++ * @brief IEEE 1588 registers to save and restore on suspend/resume
++ */
++struct ioh_1588_regs_set {
++ unsigned long ts_control;
++ unsigned long ts_event; /* not saved, cleared on restore */
++ unsigned long ts_addend;
++ unsigned long ts_accum; /* not saved/restored */
++ unsigned long ts_test; /* not saved/restored */
++ unsigned long ts_compare;
++ unsigned long ts_syslo;
++ unsigned long ts_syshi;
++ unsigned long ts_tgtlo;
++ unsigned long ts_tgthi;
++ unsigned long ts_asmslo; /* not saved/restored */
++ unsigned long ts_asmshi; /* not saved/restored */
++ unsigned long ts_ammslo; /* not saved/restored */
++ unsigned long ts_ammshi; /* not saved/restored */
++
++ /* Ethernet */
++ unsigned long ts_cc;
++ unsigned long ts_ce; /* not saved, cleared on restore */
++ unsigned long ts_xslo; /* not saved/restored */
++ unsigned long ts_xshi; /* not saved/restored */
++ unsigned long ts_rslo; /* not saved/restored */
++ unsigned long ts_rshi; /* not saved/restored */
++ unsigned long ts_uuidlo; /* not saved/restored */
++ unsigned long ts_uuidhi; /* not saved/restored */
++
++ /* CAN */
++ unsigned long ts_cce; /* not saved, cleared on restore */
++ unsigned long ts_cxslo; /* not saved/restored */
++ unsigned long ts_cxshi; /* not saved/restored */
++
++ unsigned long ts_sel; /* Selector */
++ unsigned char ts_sti[6]; /* station addresses */
++};
++
++/* callback function prototypes */
++extern void target_time_callback(struct ioh1588TimeValue targetTime);
++extern void auxiliary_time_callback(enum ioh1588AuxMode aux_mode, \
++ struct ioh1588TimeValue auxTime);
++extern void pulse_per_sec_callback(unsigned long pps);
++#endif /* IOH_1588_H */
+diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.c topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.c
+--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.c 1970-01-01 09:00:00.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.c 2010-03-09 10:32:42.000000000 +0900
+@@ -0,0 +1,700 @@
++ /*!
++ * @file ioh_1588_pci.c
++ * @brief
++ * This file contains the definitions of IEEE_1588_PCILayer APIs
++ * @version 0.92
++ * @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:
++ * modified to support Intel IOH GE IEEE 1588 hardware
++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
++ * All rights reserved.
++ * derived from
++ * IEEE 1588 Time Synchronization Driver for Intels EP80579
++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ * All rights reserved.
++ *
++ */
++
++#include "pch_1588_pci.h"
++#include "pch_1588_hal.h"
++#include "pch_debug.h"
++
++#ifdef CONFIG_PM
++static int ioh_1588_suspend(struct pci_dev *pdev, pm_message_t state);
++static int ioh_1588_resume(struct pci_dev *pdev);
++#endif
++static int ioh_1588_probe(struct pci_dev *pdev, const struct pci_device_id *id);
++static void ioh_1588_remove(struct pci_dev *pdev);
++
++/*! @ingroup IEEE_1588_PCILayerFacilitators
++ * @struct ioh_1588_pcidev_id
++ * @brief PCI device ids supported by this driver
++ * @remarks This structure is used to specify the Ids of the
++ * devices supported by the driver module during
++ * registering of the module as PCI driver.The values
++ * within the structure is maintained by the kernel
++ * subsystem to recognize the individual devices
++ * when they are attached to the system. Depending
++ * on this the corresponding device functionalities
++ * such as probe, remove, suspend,... are invoked.
++ *
++ * @note This structure contains the Vendor and device
++ * IDs of the device supported by the driver module.
++ *
++ * @see
++ * - ioh_1588_pcidev
++ * <hr>
++ */
++static const struct pci_device_id ioh_1588_pcidev_id[] = {
++ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_IOH_1588)},
++ {0},
++};
++
++/* Linux pci operations */
++/*! @ingroup IEEE_1588_PCILayerFacilitators
++* @struct ioh_1588_pcidev
++* @brief Store the references of PCI driver interfaces to kernel.
++* @remarks This strutcure is used to specify the driver specific
++* functionalities to the kernel subsystem. The kernel invokes
++* these functionalities depending on the supported device and
++* the events that occured.
++*
++* @note This structure is registered with the kernel via the call
++* pci_register_driver from @ref ioh_1588_init
++* @see
++* - ioh_1588_init
++* - ioh_1588_exit
++*<hr>
++*/
++
++static struct pci_driver ioh_1588_pcidev = {
++ .name = DRIVER_NAME,
++ .id_table = ioh_1588_pcidev_id,
++ .probe = ioh_1588_probe,
++ .remove = ioh_1588_remove,
++#ifdef CONFIG_PM
++ .suspend = ioh_1588_suspend,
++ .resume = ioh_1588_resume,
++#endif
++};
++
++/* instance of driver data structure */
++/*! @ingroup IEEE_1588_PCILayerFacilitators
++ * @var ioh_1588_dev
++ * @brief instance of driver data structure
++ * @see
++ * - ioh_1588_probe
++ * - ioh_1588_init
++ * - ioh_1588_remove
++ * - ioh_1588_suspend
++ * - ioh_1588_resume
++ * <hr>
++ */
++static struct ioh_1588_dev ioh_1588_dev;
++
++/*! @ingroup IEEE_1588_Global
++ * @var ioh_1588_devp
++ * @brief Pointer to driver data structure
++ * @see
++ * - ioc_handle_notify
++ * - ioc_handle_clr_notify
++ * - ioc_handle_reset
++ * - target_time_callback
++ * - auxiliary_time_callback
++ * - pulse_per_sec_callback
++ * - ioh_1588_open
++ * <hr>
++ */
++
++struct ioh_1588_dev *ioh_1588_devp = &ioh_1588_dev;
++
++/*! @ingroup IEEE_1588_PCILayerFacilitators
++ * @struct ioh_1588_params_
++ * @brief structure to hold the module parameters
++ * @see
++ * - ioh_1588_init
++ * - ioh_1588_probe
++ * <hr>
++ */
++static struct ioh_1588_params_ {
++ /* module parameters */
++ int eth_enable; /**< IEEE 1588 on ethernet interface
++ 0=Disabled 1=Enabled (default 1)*/
++ int can_enable; /**< IEEE 1588 on CAN interface
++ 0=Disabled 1=Enabled (default 0)*/
++ int major; /**< IEEE 1588 device major number to
++ use (default system assigned)*/
++ unsigned char station[STATION_ADDR_LEN]; /**< IEEE 1588 station address
++ to use - column separated hex values*/
++} ioh_1588_param = {
++1, 0, 0, "00:00:00:00:00:00"};
++
++module_param_named(eth_enable, ioh_1588_param.eth_enable, bool, 0444);
++MODULE_PARM_DESC(eth_enable,
++ "IEEE 1588 on ethernet interface 0=Disabled 1=Enabled \
++ (default 1)");
++
++module_param_named(can_enable, ioh_1588_param.can_enable, bool, 0444);
++MODULE_PARM_DESC(can_enable,
++ "IEEE 1588 on CAN interface 0=Disabled 1=Enabled (default 0)");
++
++module_param_named(major, ioh_1588_param.major, int, 0444);
++MODULE_PARM_DESC(major,
++ "IEEE 1588 device major number to use (default system \
++ assigned)");
++
++module_param_string(station, ioh_1588_param.station,
++ sizeof ioh_1588_param.station, 0444);
++MODULE_PARM_DESC(station,
++ "IEEE 1588 station address to use - column separated hex \
++ values");
++
++/*!@ingroup IEEE_1588_PCILayerAPI
++ * @fn int ioh_1588_probe(struct pci_dev *pdev,const struct pci_device_id *id)
++ * @brief
++ * This function is called right after insmod by the PCI core. Here we enable
++ * the
++ * device to make the device's resources live. We can then read PCI CFG space
++ * and init the device.
++ *
++ * @remarks
++ * The main tasks performed by this method are:
++ * - Allocate PCI resource required using
++ * request_mem_region API
++ * and map the memory to kernel virtual space using
++ * ioremap API.
++ * - Enable the PCI device using pci_enable_device
++ * API.
++ * - Initialize global variables and wait queues
++ * using
++ * init_waitqueue_head API
++ * - Set the memory address to be used by the HAL
++ * using ioh_1588_blpl_base_address_set API
++ * - Register the interrupt handler using request_irq
++ * API
++ * - Register the charecter driver using
++ * sregister_chrdev_region/
++ * alloc_chrdev_region APIs based on whether major
++ * number has been
++ * provided by the user or not.
++ * - Add the device to the system using the APIs
++ * cdev_init and
++ * cdev_add.
++ * - If any of the above calls fail, undo the steps
++ * performed before the failure and return
++ * appropraite error
++ * status.
++ * - Depending on the parameters passed during module
++ * load,
++ * enable/disable PTP clock synchronization control
++ * on GbE
++ * (using ioh_1588_eth_enable/ioh_1588_eth_disable
++ * API). /CAN
++ * (using ioh_1588_can_enable/ioh_1588_can_disable
++ * API) channel.
++ * - Set the Station address as specified in the
++ * module
++ * parameter using ioh_1588_set_station_address
++ * API
++ * -Note: For A0/A1 sample, test mode setting is enabled for
++ * the 64 bit System Time Register. This is a work around
++ * for
++ * the non continuous value in the 64 bit System Time
++ * Register
++ * consisting of High(32bit) / Low(32bit)
++ *
++ *
++ * @param pdev [INOUT] pci device structure
++ * @param id [IN] list of devices supported by this driver
++ *
++ * @return int
++ * - 0 Success
++ * - -ENODEV request_mem_region or ioremap or
++ * pci_enable_device or request_irq error
++ *
++ * @see
++ * - ioh_1588_pcidev
++ * <hr>
++ */
++
++static int __devinit
++ioh_1588_probe(struct pci_dev *pdev, const struct pci_device_id *id)
++{
++ int ret = 0;
++ dev_t devno;
++ int i;
++
++ UNUSED_ARG(id);
++
++ /* enable the 1588 pci device */
++ ret = pci_enable_device(pdev);
++ if (ret != 0) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_probe:could not enable the pci device\n");
++ goto exit_error;
++ }
++ IOH_DEBUG("ioh_1588_probe:pci_enable_device success\n");
++
++ ioh_1588_dev.mem_base = pci_resource_start(pdev, IO_MEM_BAR);
++
++ if (!ioh_1588_dev.mem_base) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_probe: could not locate IO memory address\n");
++ /*disable the pci device */
++ pci_disable_device(pdev);
++ ret = -ENODEV;
++ goto exit_error;
++ }
++ IOH_DEBUG("ioh_1588_probe:allocated IO memory address\n");
++
++ /* retreive the available length of the IO memory space */
++ ioh_1588_dev.mem_size = pci_resource_len(pdev, IO_MEM_BAR);
++
++ /* allocate the memory for the device registers */
++ if (!request_mem_region
++ (ioh_1588_dev.mem_base, ioh_1588_dev.mem_size, "1588_regs")) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_probe: could not allocate register memory \
++ space\n");
++ ioh_1588_dev.mem_base = 0;
++ /*disable the pci device */
++ pci_disable_device(pdev);
++ ret = -EBUSY;
++ goto exit_error;
++ }
++ IOH_DEBUG("ioh_1588_probe:allocated register memory space\n");
++
++ /* get the virtual address to the 1588 registers */
++ ioh_1588_dev.mem_virt =
++ ioremap(ioh_1588_dev.mem_base, ioh_1588_dev.mem_size);
++
++ if (!ioh_1588_dev.mem_virt) {
++ pci_disable_device(pdev);
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_probe: Could not get virtual address\n");
++ /*release memory acquired for device registers */
++ release_mem_region(ioh_1588_dev.mem_base,
++ ioh_1588_dev.mem_size);
++ ioh_1588_dev.mem_base = 0;
++ /*disable the pci device */
++ pci_disable_device(pdev);
++ ret = -ENOMEM;
++ goto exit_error;
++ }
++ IOH_DEBUG("ioh_1588_probe:obtained virtual address=%p\n",
++ ioh_1588_dev.mem_virt);
++
++ for (i = 0; i < NUM_EVENTS; i++) {
++ init_waitqueue_head(&ioh_1588_dev.notify_evt[i]);
++ ioh_1588_dev.event_flags[i] = 0;
++ }
++ IOH_DEBUG("ioh_1588_probe:initialized wait queue heads\n");
++
++ ret =
++ ioh_1588_blpl_base_address_set((unsigned int)ioh_1588_dev.mem_virt);
++ if (ret != IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_probe: ioh_1588_blpl_base_address_set \
++ failed\n");
++ /*unmap io */
++ iounmap(ioh_1588_dev.mem_virt);
++ ioh_1588_dev.mem_virt = 0;
++ /*release memory acquired for device */
++ release_mem_region(ioh_1588_dev.mem_base,
++ ioh_1588_dev.mem_size);
++ ioh_1588_dev.mem_base = 0;
++ /*disable device */
++ pci_disable_device(pdev);
++ goto exit_error;
++ }
++ IOH_DEBUG("ioh_1588_probe:set base address\n");
++
++ ret = request_irq(pdev->irq, &ioh_1588_isr, IRQF_SHARED, DRIVER_NAME,
++ &ioh_1588_dev);
++ if (ret != 0) {
++ IOH_LOG(KERN_ERR, "ioh_1588_probe: failed to get irq %d\n",
++ pdev->irq);
++ /*unmap io */
++ iounmap(ioh_1588_dev.mem_virt);
++ ioh_1588_dev.mem_virt = 0;
++ /*release memory acquired for device */
++ release_mem_region(ioh_1588_dev.mem_base,
++ ioh_1588_dev.mem_size);
++ ioh_1588_dev.mem_base = 0;
++ /*disable device */
++ pci_disable_device(pdev);
++ goto exit_error;
++ }
++ IOH_DEBUG("ioh_1588_probe:registered IRQ handler successfully\n");
++
++ /*register the module */
++ if (ioh_1588_param.major != 0) { /* user specified a major
++ number, use it */
++ IOH_DEBUG("ioh_1588_probe:using user specified major number\n");
++ devno = MKDEV(ioh_1588_param.major, 0);
++ ret = register_chrdev_region(devno, 1, DRIVER_NAME);
++ ioh_1588_dev.devno = devno; /* store it */
++ } else { /* request and reserve a device number */
++
++ IOH_DEBUG
++ ("ioh_1588_probe:dynamically allocating major number\n");
++ ret =
++ alloc_chrdev_region(&ioh_1588_dev.devno, 0, 1, DRIVER_NAME);
++ devno = MKDEV(MAJOR(ioh_1588_dev.devno), 0);
++ }
++ if (ret < 0) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_probe: Could not register module (major %d)\
++ \n",
++ ioh_1588_param.major);
++ /*free irq */
++ free_irq(pdev->irq, &ioh_1588_dev);
++ /*unmap io */
++ iounmap(ioh_1588_dev.mem_virt);
++ ioh_1588_dev.mem_virt = 0;
++ /*release memory acquired for device */
++ release_mem_region(ioh_1588_dev.mem_base,
++ ioh_1588_dev.mem_size);
++ ioh_1588_dev.mem_base = 0;
++ /*disable device */
++ pci_disable_device(pdev);
++ goto exit_error;
++ }
++ IOH_DEBUG("ioh_1588_probe:registered the module(major %d)\n",
++ ioh_1588_param.major);
++
++ /* init cdev struct for adding device to kernel */
++ cdev_init(&ioh_1588_dev.cdev, &ioh_1588_fops);
++ ioh_1588_dev.cdev.owner = THIS_MODULE;
++ ioh_1588_dev.cdev.ops = &ioh_1588_fops;
++
++ ret = cdev_add(&ioh_1588_dev.cdev, devno, 1);
++ if (ret != 0) {
++ IOH_LOG(KERN_ERR, "ioh_1588_probe: cdev_add failed\n");
++ /*free region allocated for char device */
++ unregister_chrdev_region(ioh_1588_dev.devno, 1);
++ /*free irq */
++ free_irq(pdev->irq, &ioh_1588_dev);
++ /*unmap io */
++ iounmap(ioh_1588_dev.mem_virt);
++ ioh_1588_dev.mem_virt = 0;
++ /*release memory acquired for device */
++ release_mem_region(ioh_1588_dev.mem_base,
++ ioh_1588_dev.mem_size);
++ ioh_1588_dev.mem_base = 0;
++ /*disable device */
++ pci_disable_device(pdev);
++ goto exit_error;
++ }
++ IOH_DEBUG("ioh_1588_probe: cdev_add successful\n");
++
++ ioh_1588_dev.initialized = 1;
++ /* indicate success */
++ ioh_1588_dev.irq = pdev->irq;
++
++ /*reset the ieee1588 h/w */
++ ioh_1588_reset();
++
++ if (ioh_1588_param.eth_enable != 0) { /* Enable by default */
++ IOH_DEBUG("ioh_1588_probe: invoking ioh_1588_eth_enable \
++ to enable ethernet\n");
++ (void)ioh_1588_eth_enable();
++ } else {
++ IOH_DEBUG("ioh_1588_probe: invoking ioh_1588_eth_disable \
++ to disable ethernet\n");
++ (void)ioh_1588_eth_disable();
++ }
++ if (ioh_1588_param.can_enable == 1) { /* Enable if requested */
++ IOH_DEBUG("ioh_1588_probe: invoking ioh_1588_can_enable \
++ to enable CAN\n");
++ (void)ioh_1588_can_enable();
++ } else {
++ IOH_DEBUG("ioh_1588_probe: invoking ioh_1588_can_disable \
++ to disable CAN\n");
++ (void)ioh_1588_can_disable();
++ }
++ if (strcmp(ioh_1588_param.station, "00:00:00:00:00:00") != 0) {
++ if (ioh_1588_set_station_address(ioh_1588_param.station) !=
++ IOH_1588_SUCCESS) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_probe: Invalid station address \
++ parameter\n"
++ "Module loaded; But, station address not set \
++ correctly\n");
++ }
++ }
++ IOH_DEBUG("ioh_1588_probe: probe succeeded\n");
++
++ return 0;
++
++exit_error:
++
++ IOH_LOG(KERN_ERR, "ioh_1588_probe: probe failed\n");
++ return ret;
++}
++
++/*! @ingroup IEEE_1588_PCILayerAPI
++ * @fn void ioh_1588_remove(struct pci_dev *pdev)
++ * @brief
++ * This function is called when the pci driver is being unloaded from the
++ * kernel.
++ * @remarks
++ * The main tasks performed by this method are:
++ * - Free the interrupt line using free_irq API.
++ * - Disable the PCI device using pci_disable_device API.
++ * - Unmap the PCI memory and release the same using iounmap API.
++ * - Delete the char device from the system using cdev_del API.
++ * - Unregister the driver using unregister_chrdev_region API.
++ *
++ * @param pdev [INOUT] pci device structure
++ *
++ * @return None
++ *@see
++ - ioh_1588_pcidev
++ *
++ * <hr>
++ */
++
++static void __devexit ioh_1588_remove(struct pci_dev *pdev)
++{
++ /* disable the interrupts on the 1588 hardware */
++ IOH_DEBUG("ioh_1588_remove: disabling interrupts by \
++ invoking ioh_1588_disable_interrupts\n");
++ (void)ioh_1588_disable_interrupts();
++
++ /* free the interrupt */
++ if (pdev->irq != 0) {
++ free_irq(pdev->irq, &ioh_1588_dev);
++ IOH_DEBUG("ioh_1588_remove: unregistered IRQ handler\n");
++ }
++
++ /* unmap the virtual IO memory space */
++ if (ioh_1588_dev.mem_virt != 0) {
++ iounmap(ioh_1588_dev.mem_virt);
++ IOH_DEBUG
++ ("ioh_1588_remove: unmaped the virtual IO memory space\n");
++ }
++
++ /* release the reserved IO memory space */
++ if (ioh_1588_dev.mem_base != 0) {
++ release_mem_region(ioh_1588_dev.mem_base,
++ ioh_1588_dev.mem_size);
++ IOH_DEBUG
++ ("ioh_1588_remove: released the reserved IO memory \
++ space\n");
++ }
++
++ /* remove cdev struct from system */
++ cdev_del(&ioh_1588_dev.cdev);
++ IOH_DEBUG("ioh_1588_remove: removed the cdev from system\n");
++
++ unregister_chrdev_region(ioh_1588_dev.devno, 1);
++ IOH_DEBUG("ioh_1588_remove:unregisterd the module\n");
++
++ /*disable the device */
++ pci_disable_device(pdev);
++ IOH_DEBUG("ioh_1588_remove:disabled the device\n");
++
++ IOH_LOG(KERN_ERR, "ioh_1588_remove: complete\n");
++}
++
++#ifdef CONFIG_PM
++/*! @ingroup IEEE_1588_PCILayerAPI
++ * @fn int ioh_1588_suspend(struct pci_dev *pdev,pm_message_t state)
++ * @brief
++ * This function is called to suspend a device before being put into a
++ * low power state.
++ *
++ * @remarks
++ * The main tasks performed by this method are:
++ * - Save PCI configuration space by invoking pci_save_state API.
++ * - If the above step fails, return the error from pci_save_state
++ * API.
++ * - Disable the PCI device using the pci_disable_device API.
++ * - Put the device to new power state using pci_set_power_state
++ * API.
++ *
++ *
++ * @param pdev [INOUT] pci device structure
++ * @param state [IN] suspend state
++ *
++ * @return int
++ * - 0 on success
++ * - -ENOMEM pci_save_state fails
++ *
++ * @see
++ * - ioh_1588_pcidev
++ * <hr>
++ * */
++static int ioh_1588_suspend(struct pci_dev *pdev, pm_message_t state)
++{
++
++ IOH_DEBUG("ioh_1588_suspend: disabling interrupts by \
++ invoking ioh_1588_disable_interrupts\n");
++ (void)ioh_1588_disable_interrupts();
++
++ ioh_1588_dev.suspend = 1;
++
++ IOH_DEBUG("ioh_1588_suspend: saving register values by \
++ invoking ioh_1588_save_state\n");
++ ioh_1588_save_state();
++
++ pci_disable_device(pdev);
++ IOH_DEBUG("ioh_1588_suspend: disabled the device\n");
++
++ (void)pci_enable_wake(pdev, PCI_D3hot, 0);
++ IOH_DEBUG("ioh_1588_suspend: disabled PM notifications\n");
++
++ if (pci_save_state(pdev) != 0) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_suspend: could not save PCI config state\n");
++ return -ENOMEM;
++ }
++ IOH_DEBUG("ioh_1588_suspend: saved state\n");
++
++ pci_set_power_state(pdev, pci_choose_state(pdev, state));
++
++ IOH_DEBUG("ioh_1588_suspend: returning success\n");
++ return 0;
++}
++
++/*! @ingroup IEEE_1588_PCILayerAPI
++ * @fn int ioh_1588_resume(struct pci_dev *pdev)
++ * @brief
++ * This function is called to resume a device after being put into a
++ * low power state.
++ * @remarks
++ * The main tasks performed by this method are:
++ * - Restore the power state of the device using
++ * pci_set_power_state
++ * API.
++ * - Restore the PCI configuration space using pci_restore_state
++ * API.
++ * - Enable the PCI device using pci_enable_device API.
++ * - If pci_enable_device fails, return the error status;
++ * else return 0.
++ *
++ *
++ * @param pdev [INOUT] pci device structure
++ *
++ * @return int
++ * - 0 on success
++ * - -EIO pci_enable_device fails
++ * - -EINVAL pci_enable_device fails
++ * @see
++ * - ioh_1588_pcidev
++ * <hr>
++ */
++
++static int ioh_1588_resume(struct pci_dev *pdev)
++{
++ int ret;
++
++ pci_set_power_state(pdev, PCI_D0);
++
++ ret = pci_restore_state(pdev);
++
++ if (ret != 0) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_resume: pci_restore_state failed\n");
++ return ret;
++ }
++ IOH_DEBUG("ioh_1588_resume: restored state\n");
++
++ ret = pci_enable_device(pdev);
++
++ if (ret) {
++ IOH_LOG(KERN_ERR,
++ "ioh_1588_resume: pci_enable_device failed\n");
++ return ret;
++ }
++
++ IOH_DEBUG("ioh_1588_resume: enabled device\n");
++
++ (void)pci_enable_wake(pdev, PCI_D3hot, 0);
++ IOH_DEBUG("ioh_1588_resume: disabled PM notifications\n");
++
++ IOH_DEBUG("ioh_1588_resume: restoring register values by \
++ invoking ioh_1588_restore_state\n");
++ ioh_1588_restore_state();
++
++ ioh_1588_dev.suspend = 0;
++
++ IOH_DEBUG("ioh_1588_resume: returning success\n");
++ return 0;
++}
++#endif
++
++/*! @ingroup IEEE_1588_InterfaceLayerAPI
++ * @fn void ioh_1588_exit(void)
++ * @brief Un-loads the IEEE 1588 PCI driver.
++ * @remarks This function is invoked when the driver is
++ * unloaded. The main task performed by this
++ * function is un-registering the module as
++ * PCI driver.
++ * @param None
++ * @return None
++ * <hr>
++ */
++static void __exit ioh_1588_exit(void)
++{
++
++ pci_unregister_driver(&ioh_1588_pcidev);
++
++ IOH_DEBUG("ioh_1588_exit: Driver unloaded\n");
++}
++
++/*! @ingroup IEEE_1588_InterfaceLayerAPI
++ * @fn int ioh_1588_init(void)
++ * @brief Initializes the driver.
++ * @remarks This function is the entry point for the driver.
++ * The main tasks performed by this method are:
++ * - Register IEEE 1588 driver as a PCI driver by calling
++ * pci_register_driver
++ *
++ * @param None
++ *
++ * @return int
++ * - 0 on success
++ * - -EBUSY register_chrdev_region fails
++ * - -ENOMEM cdev_add/register_chrdev_region/
++ * pci_register_driver fails
++ * - -EEXIST pci_register_driver fails
++ * - -EINVAL pci_register_driver fails
++ * <hr>
++ */
++static int __init ioh_1588_init(void)
++{
++ int ret;
++
++ (void)memset((void *)&ioh_1588_dev, 0, sizeof ioh_1588_dev);
++
++ /* register the driver with the pci core */
++ ret = pci_register_driver(&ioh_1588_pcidev);
++
++ if (ret)
++ IOH_LOG(KERN_ERR, "ioh_1588_init: pci_register failed\n");
++
++ IOH_DEBUG("ioh_1588_init: pci_register success\n");
++ return ret;
++}
++
++module_init(ioh_1588_init);
++module_exit(ioh_1588_exit);
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(pci, ioh_1588_pcidev_id);
+diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.h topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.h
+--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.h 1970-01-01 09:00:00.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.h 2010-03-09 05:27:48.000000000 +0900
+@@ -0,0 +1,122 @@
++ /*!
++ * @file ioh_1588_pci.h
++ * @brief
++ * This file lists the declarations for IEEE_1588_PCILayer APIs.
++ * @version 0.92
++ * @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:
++ * modified to support Intel IOH GE IEEE 1588 hardware
++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
++ * All rights reserved.
++ * derived from
++ * IEEE 1588 Time Synchronization Driver for Intel EP80579
++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
++ * All rights reserved.
++ *
++ */
++
++#ifndef IOH_1588_PCI_H
++#define IOH_1588_PCI_H
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/poll.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/fcntl.h>
++#include <linux/interrupt.h>
++#include <linux/uaccess.h>
++#include <linux/cdev.h>
++#include <linux/pci.h>
++
++/*! @ingroup IEEE_1588_Global
++ * @def DRIVER_NAME
++ * @brief Macro representing the name of this driver
++ * <hr>
++ */
++#define DRIVER_NAME "ioh_ieee1588"
++
++/*! @ingroup IEEE_1588_Global
++ * @def STATION_ADDR_LEN
++ * @brief Macro representing the station address length
++ * <hr>
++ */
++#define STATION_ADDR_LEN 20
++
++/*! @ingroup IEEE_1588_PCILayer
++ @def PCI_VENDOR_ID_IOH
++ @brief Outlines the PCI Vendor ID for IOH board.
++ */
++
++/*! @ingroup IEEE_1588_PCILayer
++ @def PCI_DEVICE_ID_IOH_1588
++ @brief Outlines the PCI Device ID for IEEE 1588 device.
++ */
++#define PCI_DEVICE_ID_IOH_1588 0x8819
++
++/*! @ingroup IEEE_1588_PCILayer
++ * @def IO_MEM_BAR
++ * @brief Macro representing IO memory BAR
++ * <hr>
++ */
++#define IO_MEM_BAR 1
++
++/* enumeration of events used */
++
++/*! @ingroup IEEE_1588_Global
++ * @enum notify_event
++ * @brief enumeration of events used
++ * <hr>
++ */
++enum _notify_event {
++ TARG_TIME_EVENT_NUM,
++ AUX_TIME_EVENT_NUM,
++ PPS_EVENT_NUM,
++ NUM_EVENTS
++};
++
++/* private driver data */
++/*! @ingroup IEEE_1588_Global
++ * @struct ioh_1588_dev_t
++ * @brief Driver private data
++ * <hr>
++ */
++struct ioh_1588_dev {
++ dev_t devno; /**< The device (major) number. */
++ struct cdev cdev; /**< The cdev structure instance. */
++ void *mem_virt; /**< The virtual memory base address.*/
++ unsigned int mem_base; /**< The physical memory base address.*/
++ unsigned int mem_size; /**< The memory size. */
++ unsigned int irq; /**< The IRQ line of the device.*/
++ unsigned int suspend:1; /**< The suspend flag. */
++ unsigned int initialized:1; /**< The initialized flag. */
++ /* event variables */
++ unsigned int event_flags[NUM_EVENTS]; /**< The event variables. */
++ wait_queue_head_t notify_evt[NUM_EVENTS]; /**< The notify event
++ variable.*/
++};
++
++extern struct ioh_1588_dev *ioh_1588_devp;
++extern const struct file_operations ioh_1588_fops;
++irqreturn_t ioh_1588_isr(int irq, void *p_data);
++extern void ioh_1588_save_state(void);
++extern void ioh_1588_restore_state(void);
++
++#endif /* IOH_1588_PCI_H */
+diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_common.h topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_common.h
+--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_common.h 1970-01-01 09:00:00.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/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/char/pch_ieee1588/pch_debug.h topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_debug.h
+--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_debug.h 1970-01-01 09:00:00.000000000 +0900
++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/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