diff options
author | Felix Fietkau <nbd@openwrt.org> | 2005-11-07 01:10:50 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2005-11-07 01:10:50 +0000 |
commit | 816e158a73c253f73d53ec19c73cf6c7ea2e3736 (patch) | |
tree | d843a9769f1865a81a69f82ca40a31baff10d95d /target/linux/linux-2.4/patches/ar7/005-vlynq.patch | |
parent | 4b35b398e164435584632da09eafa03f295921e3 (diff) | |
download | upstream-816e158a73c253f73d53ec19c73cf6c7ea2e3736.tar.gz upstream-816e158a73c253f73d53ec19c73cf6c7ea2e3736.tar.bz2 upstream-816e158a73c253f73d53ec19c73cf6c7ea2e3736.zip |
add first batch of enrik's ar7 system code cleanups
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@2363 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/linux-2.4/patches/ar7/005-vlynq.patch')
-rw-r--r-- | target/linux/linux-2.4/patches/ar7/005-vlynq.patch | 2316 |
1 files changed, 0 insertions, 2316 deletions
diff --git a/target/linux/linux-2.4/patches/ar7/005-vlynq.patch b/target/linux/linux-2.4/patches/ar7/005-vlynq.patch deleted file mode 100644 index ee76d4774b..0000000000 --- a/target/linux/linux-2.4/patches/ar7/005-vlynq.patch +++ /dev/null @@ -1,2316 +0,0 @@ -diff -urN linux.old/drivers/char/avalanche_vlynq/Makefile linux.dev/drivers/char/avalanche_vlynq/Makefile ---- linux.old/drivers/char/avalanche_vlynq/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/char/avalanche_vlynq/Makefile 2005-07-22 06:32:53.345189608 +0200 -@@ -0,0 +1,14 @@ -+# -+# Makefile for the linux kernel. -+# -+# Note! Dependencies are done automagically by 'make dep', which also -+# removes any old dependencies. DON'T put your own dependencies here -+# unless it's something special (ie not a .c file). -+# -+# Note 2! The CFLAGS definitions are now in the main makefile... -+ -+O_TARGET := avalanche_vlynq.o -+ -+obj-y += vlynq_drv.o vlynq_hal.o vlynq_board.o -+ -+include $(TOPDIR)/Rules.make -diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_board.c linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c ---- linux.old/drivers/char/avalanche_vlynq/vlynq_board.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c 2005-07-22 06:34:39.448059520 +0200 -@@ -0,0 +1,182 @@ -+/* -+ * Jeff Harrell, jharrell@ti.com -+ * Copyright (C) 2001 Texas Instruments, Inc. All rights reserved. -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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. -+ * -+ * Texas Instruments Sangam specific setup. -+ */ -+#include <linux/config.h> -+#include <asm/ar7/sangam.h> -+#include <asm/ar7/avalanche_misc.h> -+#include <asm/ar7/vlynq.h> -+ -+#define SYS_VLYNQ_LOCAL_INTERRUPT_VECTOR 30 /* MSB - 1 bit */ -+#define SYS_VLYNQ_REMOTE_INTERRUPT_VECTOR 31 /* MSB bit */ -+#define SYS_VLYNQ_OPTIONS 0x7F; /* all options*/ -+ -+/* These defines are board specific */ -+ -+ -+#define VLYNQ0_REMOTE_WINDOW1_OFFSET (0x0C000000) -+#define VLYNQ0_REMOTE_WINDOW1_SIZE (0x500) -+ -+ -+#define VLYNQ1_REMOTE_WINDOW1_OFFSET (0x0C000000) -+#define VLYNQ1_REMOTE_WINDOW1_SIZE (0x500) -+ -+ -+extern VLYNQ_DEV vlynqDevice0, vlynqDevice1; -+int vlynq_init_status[2] = {0, 0}; -+static int reset_hack = 1; -+ -+void vlynq_ar7wrd_dev_init() -+{ -+ *(unsigned long*) AVALANCHE_GPIO_ENBL |= (1<<18); -+ vlynq_delay(20000); -+ *(unsigned long*) AVALANCHE_GPIO_DIR &= ~(1<<18); -+ vlynq_delay(20000); -+ *(unsigned long*) AVALANCHE_GPIO_DATA_OUT&= ~(1<<18); -+ vlynq_delay(50000); -+ *(unsigned long*) AVALANCHE_GPIO_DATA_OUT|= (1<<18); -+ vlynq_delay(50000); -+ -+ /* Initialize the MIPS host vlynq driver for a given vlynq interface */ -+ vlynqDevice0.dev_idx = 0; /* first vlynq module - this parameter is for reference only */ -+ vlynqDevice0.module_base = AVALANCHE_LOW_VLYNQ_CONTROL_BASE; /* vlynq0 module base address */ -+ -+#if defined(CONFIG_VLYNQ_CLK_LOCAL) -+ vlynqDevice0.clk_source = VLYNQ_CLK_SOURCE_LOCAL; -+#else -+ vlynqDevice0.clk_source = VLYNQ_CLK_SOURCE_REMOTE; -+#endif -+ vlynqDevice0.clk_div = 0x01; /* board/hardware specific */ -+ vlynqDevice0.state = VLYNQ_DRV_STATE_UNINIT; /* uninitialized module */ -+ -+ /* Populate vlynqDevice0.local_mem & Vlynq0.remote_mem based on system configuration */ -+ /*Local memory configuration */ -+ -+ /* Demiurg : not good !*/ -+#if 0 -+ vlynqDevice0.local_mem.Txmap= AVALANCHE_LOW_VLYNQ_MEM_MAP_BASE & ~(0xc0000000) ; /* physical address */ -+ vlynqDevice0.remote_mem.RxOffset[0]= VLYNQ0_REMOTE_WINDOW1_OFFSET; /* This is specific to the board on the other end */ -+ vlynqDevice0.remote_mem.RxSize[0]=VLYNQ0_REMOTE_WINDOW1_SIZE; -+#endif -+ -+ /* Demiurg : This is how it should be ! */ -+ vlynqDevice0.local_mem.Txmap = PHYSADDR(AVALANCHE_LOW_VLYNQ_MEM_MAP_BASE); -+#define VLYNQ_ACX111_MEM_OFFSET 0xC0000000 /* Physical address of ACX111 memory */ -+#define VLYNQ_ACX111_MEM_SIZE 0x00040000 /* Total size of the ACX111 memory */ -+#define VLYNQ_ACX111_REG_OFFSET 0xF0000000 /* PHYS_ADDR of ACX111 control registers */ -+#define VLYNQ_ACX111_REG_SIZE 0x00022000 /* Size of ACX111 registers area, MAC+PHY */ -+#define ACX111_VL1_REMOTE_SIZE 0x1000000 -+ vlynqDevice0.remote_mem.RxOffset[0] = VLYNQ_ACX111_MEM_OFFSET; -+ vlynqDevice0.remote_mem.RxSize[0] = VLYNQ_ACX111_MEM_SIZE ; -+ vlynqDevice0.remote_mem.RxOffset[1] = VLYNQ_ACX111_REG_OFFSET; -+ vlynqDevice0.remote_mem.RxSize[1] = VLYNQ_ACX111_REG_SIZE ; -+ vlynqDevice0.remote_mem.Txmap = 0; -+ vlynqDevice0.local_mem.RxOffset[0] = AVALANCHE_SDRAM_BASE; -+ vlynqDevice0.local_mem.RxSize[0] = ACX111_VL1_REMOTE_SIZE; -+ -+ -+ /* Local interrupt configuration */ -+ vlynqDevice0.local_irq.intLocal = VLYNQ_INT_LOCAL; /* Host handles vlynq interrupts*/ -+ vlynqDevice0.local_irq.intRemote = VLYNQ_INT_ROOT_ISR; /* vlynq root isr used */ -+ vlynqDevice0.local_irq.map_vector = SYS_VLYNQ_LOCAL_INTERRUPT_VECTOR; -+ vlynqDevice0.local_irq.intr_ptr = 0; /* Since remote interrupts part of vlynq root isr this is unused */ -+ -+ /* Remote interrupt configuration */ -+ vlynqDevice0.remote_irq.intLocal = VLYNQ_INT_REMOTE; /* MIPS handles interrupts */ -+ vlynqDevice0.remote_irq.intRemote = VLYNQ_INT_ROOT_ISR; /* Not significant since MIPS handles interrupts */ -+ vlynqDevice0.remote_irq.map_vector = SYS_VLYNQ_REMOTE_INTERRUPT_VECTOR; -+ vlynqDevice0. remote_irq.intr_ptr = AVALANCHE_INTC_BASE; /* Not significant since MIPS handles interrupts */ -+ -+ if(reset_hack != 1) -+ printk("About to re-init the VLYNQ.\n"); -+ -+ if(vlynq_init(&vlynqDevice0,VLYNQ_INIT_PERFORM_ALL)== 0) -+ { -+ /* Suraj added the following to keep the 1130 going. */ -+ vlynq_interrupt_vector_set(&vlynqDevice0, 0 /* intr vector line running into 1130 vlynq */, -+ 0 /* intr mapped onto the interrupt register on remote vlynq and this vlynq */, -+ VLYNQ_REMOTE_DVC, 0 /* polarity active high */, 0 /* interrupt Level triggered */); -+ -+ /* System wide interrupt is 80 for 1130, please note. */ -+ vlynq_init_status[0] = 1; -+ reset_hack = 2; -+ } -+ else -+ { -+ if(reset_hack == 1) -+ printk("VLYNQ INIT FAILED: Please try cold reboot. \n"); -+ else -+ printk("Failed to initialize the VLYNQ interface at insmod.\n"); -+ -+ } -+} -+ -+void vlynq_dev_init(void) -+{ -+ volatile unsigned int *reset_base = (unsigned int *) AVALANCHE_RESET_CONTROL_BASE; -+ -+ *reset_base &= ~((1 << AVALANCHE_LOW_VLYNQ_RESET_BIT)); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT)); */ -+ -+ vlynq_delay(20000); -+ -+ /* Bring vlynq out of reset if not already done */ -+ *reset_base |= (1 << AVALANCHE_LOW_VLYNQ_RESET_BIT); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT); */ -+ vlynq_delay(20000); /* Allowing sufficient time to VLYNQ to settle down.*/ -+ -+ vlynq_ar7wrd_dev_init( ); -+ -+} -+ -+/* This function is board specific and should be ported for each board. */ -+void remote_vlynq_dev_reset_ctrl(unsigned int module_reset_bit, -+ AVALANCHE_RESET_CTRL_T reset_ctrl) -+{ -+ if(module_reset_bit >= 32) -+ return; -+ -+ switch(module_reset_bit) -+ { -+ case 0: -+ if(OUT_OF_RESET == reset_ctrl) -+ { -+ if(reset_hack) return; -+ -+ vlynq_delay(20000); -+ printk("Un-resetting the remote device.\n"); -+ vlynq_dev_init(); -+ printk("Re-initialized the VLYNQ.\n"); -+ reset_hack = 2; -+ } -+ else if(IN_RESET == reset_ctrl) -+ { -+ *(unsigned long*) AVALANCHE_GPIO_DATA_OUT &= ~(1<<18); -+ -+ vlynq_delay(20000); -+ printk("Resetting the remote device.\n"); -+ reset_hack = 0; -+ } -+ else -+ ; -+ break; -+ -+ default: -+ break; -+ -+ } -+} -+ -diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c ---- linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c 2005-07-22 06:32:53.345189608 +0200 -@@ -0,0 +1,242 @@ -+/****************************************************************************** -+ * FILE PURPOSE: Vlynq Linux Device Driver Source -+ ****************************************************************************** -+ * FILE NAME: vlynq_drv.c -+ * -+ * DESCRIPTION: Vlynq Linux Device Driver Source -+ * -+ * REVISION HISTORY: -+ * -+ * Date Description Author -+ *----------------------------------------------------------------------------- -+ * 17 July 2003 Initial Creation Anant Gole -+ * 17 Dec 2003 Updates Sharath Kumar -+ * -+ * (C) Copyright 2003, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+#include <linux/config.h> -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/sched.h> -+#include <linux/miscdevice.h> -+#include <linux/smp_lock.h> -+#include <linux/delay.h> -+#include <linux/proc_fs.h> -+#include <linux/capability.h> -+#include <asm/ar7/avalanche_intc.h> -+#include <asm/ar7/sangam.h> -+#include <asm/ar7/vlynq.h> -+ -+ -+#define TI_VLYNQ_VERSION "0.2" -+ -+/* debug on ? */ -+#define VLYNQ_DEBUG -+ -+/* Macro for debug and error printf's */ -+#ifdef VLYNQ_DEBUG -+#define DBGPRINT printk -+#else -+#define DBGPRINT(x) -+#endif -+ -+#define ERRPRINT printk -+ -+/* Define the max vlynq ports this driver will support. -+ Device name strings are statically added here */ -+#define MAX_VLYNQ_PORTS 2 -+ -+ -+/* Type define for VLYNQ private structure */ -+typedef struct vlynqPriv{ -+ int irq; -+ VLYNQ_DEV *vlynqDevice; -+}VLYNQ_PRIV; -+ -+extern int vlynq_init_status[2]; -+ -+/* Extern Global variable for vlynq devices used in initialization of the vlynq device -+ * These variables need to be populated/initialized by the system as part of initialization -+ * process. The vlynq enumerator can run at initialization and populate these globals -+ */ -+ -+VLYNQ_DEV vlynqDevice0; -+VLYNQ_DEV vlynqDevice1; -+ -+/* Defining dummy macro AVALANCHE_HIGH_VLYNQ_INT to take -+ * care of compilation in case of single vlynq device -+ */ -+ -+#ifndef AVALANCHE_HIGH_VLYNQ_INT -+#define AVALANCHE_HIGH_VLYNQ_INT 0 -+#endif -+ -+ -+ -+/* vlynq private object */ -+VLYNQ_PRIV vlynq_priv[CONFIG_AR7_VLYNQ_PORTS] = { -+ { LNXINTNUM(AVALANCHE_LOW_VLYNQ_INT),&vlynqDevice0}, -+ { LNXINTNUM(AVALANCHE_HIGH_VLYNQ_INT),&vlynqDevice1}, -+}; -+ -+extern void vlynq_dev_init(void); -+ -+ -+/* =================================== all the operations */ -+ -+static int -+vlynq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ return 0; -+} -+ -+static struct file_operations vlynq_fops = { -+ owner: THIS_MODULE, -+ ioctl: vlynq_ioctl, -+}; -+ -+/* Vlynq device object */ -+static struct miscdevice vlynq_dev [MAX_VLYNQ_PORTS] = { -+ { MISC_DYNAMIC_MINOR , "vlynq0", &vlynq_fops }, -+ { MISC_DYNAMIC_MINOR , "vlynq1", &vlynq_fops }, -+}; -+ -+ -+/* Proc read function */ -+static int -+vlynq_read_link_proc(char *buf, char **start, off_t offset, int count, int *eof, void *unused) -+{ -+ int instance; -+ int len = 0; -+ -+ len += sprintf(buf +len,"VLYNQ Devices : %d\n",CONFIG_AR7_VLYNQ_PORTS); -+ -+ for(instance =0;instance < CONFIG_AR7_VLYNQ_PORTS;instance++) -+ { -+ int link_state; -+ char *link_msg[] = {" DOWN "," UP "}; -+ -+ if(vlynq_init_status[instance] == 0) -+ link_state = 0; -+ -+ else if (vlynq_link_check(vlynq_priv[instance].vlynqDevice)) -+ link_state = 1; -+ -+ else -+ link_state = 0; -+ -+ len += sprintf(buf + len, "VLYNQ %d: Link state: %s\n",instance,link_msg[link_state]); -+ -+ } -+ /* Print info about vlynq device 1 */ -+ -+ return len; -+} -+ -+ -+/* Proc function to display driver version */ -+static int -+vlynq_read_ver_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+{ -+ int instance; -+ int len=0; -+ -+ len += sprintf(buf +len,"\nTI Linux VLYNQ Driver Version %s\n",TI_VLYNQ_VERSION); -+ return len; -+} -+ -+ -+ -+ -+/* Wrapper for vlynq ISR */ -+static void lnx_vlynq_root_isr(int irq, void * arg, struct pt_regs *regs) -+{ -+ vlynq_root_isr(arg); -+} -+ -+/* =================================== init and cleanup */ -+ -+int vlynq_init_module(void) -+{ -+ int ret; -+ int unit = 0; -+ int instance_count = CONFIG_AR7_VLYNQ_PORTS; -+ volatile int *ptr; -+ -+ vlynq_dev_init(); -+ -+ DBGPRINT("Vlynq CONFIG_AR7_VLYNQ_PORTS=%d\n", CONFIG_AR7_VLYNQ_PORTS); -+ /* If num of configured vlynq ports > supported by driver return error */ -+ if (instance_count > MAX_VLYNQ_PORTS) -+ { -+ ERRPRINT("ERROR: vlynq_init_module(): Max %d supported\n", MAX_VLYNQ_PORTS); -+ return (-1); -+ } -+ -+ /* register the misc device */ -+ for (unit = 0; unit < CONFIG_AR7_VLYNQ_PORTS; unit++) -+ { -+ ret = misc_register(&vlynq_dev[unit]); -+ -+ if(ret < 0) -+ { -+ ERRPRINT("ERROR:Could not register vlynq device:%d\n",unit); -+ continue; -+ } -+ else -+ DBGPRINT("Vlynq Device %s registered with minor no %d as misc device. Result=%d\n", -+ vlynq_dev[unit].name, vlynq_dev[unit].minor, ret); -+#if 0 -+ -+ DBGPRINT("Calling vlynq init\n"); -+ -+ /* Read the global variable for VLYNQ device structure and initialize vlynq driver */ -+ ret = vlynq_init(vlynq_priv[unit].vlynqDevice,VLYNQ_INIT_PERFORM_ALL ); -+#endif -+ -+ if(vlynq_init_status[unit] == 0) -+ { -+ printk("VLYNQ %d : init failed\n",unit); -+ continue; -+ } -+ -+ /* Check link before proceeding */ -+ if (!vlynq_link_check(vlynq_priv[unit].vlynqDevice)) -+ { -+ DBGPRINT("\nError: Vlynq link not available.trying once before Exiting"); -+ } -+ else -+ { -+ DBGPRINT("Vlynq instance:%d Link UP\n",unit); -+ -+ /* Install the vlynq local root ISR */ -+ request_irq(vlynq_priv[unit].irq,lnx_vlynq_root_isr,0,vlynq_dev[unit].name,vlynq_priv[unit].vlynqDevice); -+ } -+ } -+ -+ /* Creating proc entry for the devices */ -+ create_proc_read_entry("avalanche/vlynq_link", 0, NULL, vlynq_read_link_proc, NULL); -+ create_proc_read_entry("avalanche/vlynq_ver", 0, NULL, vlynq_read_ver_proc, NULL); -+ -+ return 0; -+} -+ -+void vlynq_cleanup_module(void) -+{ -+ int unit = 0; -+ -+ for (unit = 0; unit < CONFIG_AR7_VLYNQ_PORTS; unit++) -+ { -+ DBGPRINT("vlynq_cleanup_module(): Unregistring misc device %s\n",vlynq_dev[unit].name); -+ misc_deregister(&vlynq_dev[unit]); -+ } -+ -+ remove_proc_entry("avalanche/vlynq_link", NULL); -+ remove_proc_entry("avalanche/vlynq_ver", NULL); -+} -+ -+ -+module_init(vlynq_init_module); -+module_exit(vlynq_cleanup_module); -+ -diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c ---- linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c 2005-07-22 06:32:53.359187480 +0200 -@@ -0,0 +1,1214 @@ -+/*************************************************************************** -+**+----------------------------------------------------------------------+** -+**| **** |** -+**| **** |** -+**| ******o*** |** -+**| ********_///_**** |** -+**| ***** /_//_/ **** |** -+**| ** ** (__/ **** |** -+**| ********* |** -+**| **** |** -+**| *** |** -+**| |** -+**| Copyright (c) 2003 Texas Instruments Incorporated |** -+**| ALL RIGHTS RESERVED |** -+**| |** -+**| Permission is hereby granted to licensees of Texas Instruments |** -+**| Incorporated (TI) products to use this computer program for the sole |** -+**| purpose of implementing a licensee product based on TI products. |** -+**| No other rights to reproduce, use, or disseminate this computer |** -+**| program, whether in part or in whole, are granted. |** -+**| |** -+**| TI makes no representation or warranties with respect to the |** -+**| performance of this computer program, and specifically disclaims |** -+**| any responsibility for any damages, special or consequential, |** -+**| connected with the use of this program. |** -+**| |** -+**+----------------------------------------------------------------------+** -+***************************************************************************/ -+ -+/*************************************************************************** -+ * ------------------------------------------------------------------------------ -+ * Module : vlynq_hal.c -+ * Description : This file implements VLYNQ HAL API. -+ * ------------------------------------------------------------------------------ -+ ***************************************************************************/ -+ -+#include <linux/stddef.h> -+#include <linux/types.h> -+#include <asm/ar7/vlynq.h> -+ -+/**** Local Function prototypes *******/ -+static int vlynqInterruptInit(VLYNQ_DEV *pdev); -+static void vlynq_configClock(VLYNQ_DEV *pdev); -+ -+/*** Second argument must be explicitly type casted to -+ * (VLYNQ_DEV*) inside the following functions */ -+static void vlynq_local_module_isr(void *arg1, void *arg2, void *arg3); -+static void vlynq_remote_module_isr(void *arg1, void *arg2, void *arg3); -+ -+ -+volatile int vlynq_delay_value = 0; -+ -+/* Code adopted from original vlynq driver */ -+void vlynq_delay(unsigned int clktime) -+{ -+ int i = 0; -+ volatile int *ptr = &vlynq_delay_value; -+ *ptr = 0; -+ -+ /* We are assuming that the each cycle takes about -+ * 23 assembly instructions. */ -+ for(i = 0; i < (clktime + 23)/23; i++) -+ { -+ *ptr = *ptr + 1; -+ } -+} -+ -+ -+/* ---------------------------------------------------------------------------- -+ * Function : vlynq_configClock() -+ * Description: Configures clock settings based on input parameters -+ * Adapted from original vlyna driver from Cable -+ */ -+static void vlynq_configClock(VLYNQ_DEV * pdev) -+{ -+ unsigned int tmp; -+ -+ switch( pdev->clk_source) -+ { -+ case VLYNQ_CLK_SOURCE_LOCAL: /* we output the clock, clk_div in range [1..8]. */ -+ tmp = ((pdev->clk_div - 1) << 16) | VLYNQ_CTL_CLKDIR_MASK ; -+ VLYNQ_CTRL_REG = tmp; -+ VLYNQ_R_CTRL_REG = 0ul; -+ break; -+ case VLYNQ_CLK_SOURCE_REMOTE: /* we need to set the clock pin as input */ -+ VLYNQ_CTRL_REG = 0ul; -+ tmp = ((pdev->clk_div - 1) << 16) | VLYNQ_CTL_CLKDIR_MASK ; -+ VLYNQ_R_CTRL_REG = tmp; -+ break; -+ default: /* do nothing about the clock, but clear other bits. */ -+ tmp = ~(VLYNQ_CTL_CLKDIR_MASK | VLYNQ_CTL_CLKDIV_MASK); -+ VLYNQ_CTRL_REG &= tmp; -+ break; -+ } -+} -+ -+ /* ---------------------------------------------------------------------------- -+ * Function : vlynq_link_check() -+ * Description: This function checks the current VLYNQ for a link. -+ * An arbitrary amount of time is allowed for the link to come up . -+ * Returns 0 for "no link / failure " and 1 for "link available". -+ * ----------------------------------------------------------------------------- -+ */ -+unsigned int vlynq_link_check( VLYNQ_DEV * pdev) -+{ -+ /*sleep for 64 cycles, allow link to come up*/ -+ vlynq_delay(64); -+ -+ /* check status register return OK if link is found. */ -+ if (VLYNQ_STATUS_REG & VLYNQ_STS_LINK_MASK) -+ { -+ return 1; /* Link Available */ -+ } -+ else -+ { -+ return 0; /* Link Failure */ -+ } -+} -+ -+/* ---------------------------------------------------------------------------- -+ * Function : vlynq_init() -+ * Description: Initialization function accepting paramaters for VLYNQ module -+ * initialization. The Options bitmap decides what operations are performed -+ * as a part of initialization. The Input parameters are obtained through the -+ * sub fields of VLYNQ_DEV structure. -+ */ -+ -+int vlynq_init(VLYNQ_DEV *pdev, VLYNQ_INIT_OPTIONS options) -+{ -+ unsigned int map; -+ unsigned int val=0,cnt,tmp; -+ unsigned int counter=0; -+ VLYNQ_INTERRUPT_CNTRL *intSetting=NULL; -+ -+ /* validate arguments */ -+ if( VLYNQ_OUTRANGE(pdev->clk_source, VLYNQ_CLK_SOURCE_REMOTE, VLYNQ_CLK_SOURCE_NONE) || -+ VLYNQ_OUTRANGE(pdev->clk_div, 8, 1) ) -+ { -+ return VLYNQ_INVALID_ARG; -+ } -+ -+ /** perform all sanity checks first **/ -+ if(pdev->state != VLYNQ_DRV_STATE_UNINIT) -+ return VLYNQ_INVALID_DRV_STATE; -+ -+ /** Initialize local and remote register set addresses- additional -+ * provision to access the registers directly if need be */ -+ pdev->local = (VLYNQ_REG_SET*)pdev->module_base; -+ pdev->remote = (VLYNQ_REG_SET*) (pdev->module_base + VLYNQ_REMOTE_REGS_OFFSET); -+ -+ /* Detect faulty int configuration that might induce int pkt looping */ -+ if ( (options & VLYNQ_INIT_LOCAL_INTERRUPTS) && (options & VLYNQ_INIT_REMOTE_INTERRUPTS) ) -+ { -+ /* case when both local and remote are configured */ -+ if((pdev->local_irq.intLocal== VLYNQ_INT_REMOTE ) /* interrupts transfered to remote from local */ -+ && (pdev->remote_irq.intLocal== VLYNQ_INT_REMOTE) /* interrupts transfered from remote to local */ -+ && ((pdev->local_irq.intRemote == VLYNQ_INT_ROOT_ISR) || (pdev->remote_irq.intRemote == VLYNQ_INT_ROOT_ISR)) ) -+ { -+ return (VLYNQ_INT_CONFIG_ERR); -+ } -+ } -+ -+ pdev->state = VLYNQ_DRV_STATE_ININIT; -+ pdev->intCount = 0; -+ pdev->isrCount = 0; -+ -+ /*** Its assumed that the vlynq module has been brought out of reset -+ * before invocation of vlynq_init. Since, this operation is board specific -+ * it must be handled outside this generic driver */ -+ -+ /* Assert reset the remote device, call reset_cb, -+ * reset CB holds Reset according to the device needs. */ -+ VLYNQ_RESETCB(VLYNQ_RESET_ASSERT); -+ -+ /* Handle VLYNQ clock, HW default (Sense On Reset) is -+ * usually input for all the devices. */ -+ if (options & VLYNQ_INIT_CONFIG_CLOCK) -+ { -+ vlynq_configClock(pdev); -+ } -+ -+ /* Call reset_cb again. It will release the remote device -+ * from reset, and wait for a while. */ -+ VLYNQ_RESETCB(VLYNQ_RESET_DEASSERT); -+ -+ if(options & VLYNQ_INIT_CHECK_LINK ) -+ { -+ /* Check for link up during initialization*/ -+ while( counter < 25 ) -+ { -+ /* loop around giving a chance for link status to settle down */ -+ counter++; -+ if(vlynq_link_check(pdev)) -+ { -+ /* Link is up exit loop*/ -+ break; -+ } -+ -+ vlynq_delay(4000); -+ }/*end of while counter loop */ -+ -+ if(!vlynq_link_check(pdev)) -+ { -+ /* Handle this case as abort */ -+ pdev->state = VLYNQ_DRV_STATE_ERROR; -+ VLYNQ_RESETCB( VLYNQ_RESET_INITFAIL); -+ return VLYNQ_LINK_DOWN; -+ }/* end of if not vlynq_link_check conditional block */ -+ -+ }/*end of if options & VLYNQ_INIT_CHECK_LINK conditional block */ -+ -+ -+ if (options & VLYNQ_INIT_LOCAL_MEM_REGIONS) -+ { -+ /* Initialise local memory regions . This initialization lets -+ * the local host access remote device memory regions*/ -+ int i; -+ -+ /* configure the VLYNQ portal window to a PHYSICAL -+ * address of the local CPU */ -+ VLYNQ_ALIGN4(pdev->local_mem.Txmap); -+ VLYNQ_TXMAP_REG = (pdev->local_mem.Txmap); -+ -+ /*This code assumes input parameter is itself a physical address */ -+ for(i=0; i < VLYNQ_MAX_MEMORY_REGIONS ; i++) -+ { -+ /* Physical address on the remote */ -+ map = i+1; -+ VLYNQ_R_RXMAP_SIZE_REG(map) = 0; -+ if( pdev->remote_mem.RxSize[i]) -+ { -+ VLYNQ_ALIGN4(pdev->remote_mem.RxOffset[i]); -+ VLYNQ_ALIGN4(pdev->remote_mem.RxSize[i]); -+ VLYNQ_R_RXMAP_OFFSET_REG(map) = pdev->remote_mem.RxOffset[i]; -+ VLYNQ_R_RXMAP_SIZE_REG(map) = pdev->remote_mem.RxSize[i]; -+ } -+ } -+ } -+ -+ if(options & VLYNQ_INIT_REMOTE_MEM_REGIONS ) -+ { -+ int i; -+ -+ /* Initialise remote memory regions. This initialization lets remote -+ * device access local host memory regions. It configures the VLYNQ portal -+ * window to a PHYSICAL address of the remote */ -+ VLYNQ_ALIGN4(pdev->remote_mem.Txmap); -+ VLYNQ_R_TXMAP_REG = pdev->remote_mem.Txmap; -+ -+ for( i=0; i<VLYNQ_MAX_MEMORY_REGIONS; i++) -+ { -+ /* Physical address on the local */ -+ map = i+1; -+ VLYNQ_RXMAP_SIZE_REG(map) = 0; -+ if( pdev->local_mem.RxSize[i]) -+ { -+ VLYNQ_ALIGN4(pdev->local_mem.RxOffset[i]); -+ VLYNQ_ALIGN4(pdev->local_mem.RxSize[i]); -+ VLYNQ_RXMAP_OFFSET_REG(map) = (pdev->local_mem.RxOffset[i]); -+ VLYNQ_RXMAP_SIZE_REG(map) = (pdev->local_mem.RxSize[i]); -+ } -+ } -+ } -+ -+ /* Adapted from original vlynq driver from cable - Calculate VLYNQ bus width */ -+ pdev->width = 3 + VLYNQ_STATUS_FLD_WIDTH(VLYNQ_STATUS_REG) -+ + VLYNQ_STATUS_FLD_WIDTH(VLYNQ_R_STATUS_REG); -+ -+ /* chance to initialize the device, e.g. to boost VLYNQ -+ * clock by modifying pdev->clk_div or and verify the width. */ -+ VLYNQ_RESETCB(VLYNQ_RESET_LINKESTABLISH); -+ -+ /* Handle VLYNQ clock, HW default (Sense On Reset) is -+ * usually input for all the devices. */ -+ if(options & VLYNQ_INIT_CONFIG_CLOCK ) -+ { -+ vlynq_configClock(pdev); -+ } -+ -+ /* last check for link*/ -+ if(options & VLYNQ_INIT_CHECK_LINK ) -+ { -+ /* Final Check for link during initialization*/ -+ while( counter < 25 ) -+ { -+ /* loop around giving a chance for link status to settle down */ -+ counter++; -+ if(vlynq_link_check(pdev)) -+ { -+ /* Link is up exit loop*/ -+ break; -+ } -+ -+ vlynq_delay(4000); -+ }/*end of while counter loop */ -+ -+ if(!vlynq_link_check(pdev)) -+ { -+ /* Handle this case as abort */ -+ pdev->state = VLYNQ_DRV_STATE_ERROR; -+ VLYNQ_RESETCB( VLYNQ_RESET_INITFAIL); -+ return VLYNQ_LINK_DOWN; -+ }/* end of if not vlynq_link_check conditional block */ -+ -+ } /* end of if options & VLYNQ_INIT_CHECK_LINK */ -+ -+ if(options & VLYNQ_INIT_LOCAL_INTERRUPTS ) -+ { -+ /* Configure local interrupt settings */ -+ intSetting = &(pdev->local_irq); -+ -+ /* Map local module status interrupts to interrupt vector*/ -+ val = intSetting->map_vector << VLYNQ_CTL_INTVEC_SHIFT ; -+ -+ /* enable local module status interrupts */ -+ val |= 0x01 << VLYNQ_CTL_INTEN_SHIFT; -+ -+ if ( intSetting->intLocal == VLYNQ_INT_LOCAL ) -+ { -+ /*set the intLocal bit*/ -+ val |= 0x01 << VLYNQ_CTL_INTLOCAL_SHIFT; -+ } -+ -+ /* Irrespective of whether interrupts are handled locally, program -+ * int2Cfg. Error checking for accidental loop(when intLocal=0 and int2Cfg=1 -+ * i.e remote packets are set intPending register->which will result in -+ * same packet being sent out) has been done already -+ */ -+ -+ if (intSetting->intRemote == VLYNQ_INT_ROOT_ISR) -+ { -+ /* Set the int2Cfg register, so that remote interrupt -+ * packets are written to intPending register */ -+ val |= 0x01 << VLYNQ_CTL_INT2CFG_SHIFT; -+ -+ /* Set intPtr register to point to intPending register */ -+ VLYNQ_INT_PTR_REG = VLYNQ_INT_PENDING_REG_PTR ; -+ } -+ else -+ { -+ /*set the interrupt pointer register*/ -+ VLYNQ_INT_PTR_REG = intSetting->intr_ptr; -+ /* Dont bother to modify int2Cfg as it would be zero */ -+ } -+ -+ /** Clear bits related to INT settings in control register **/ -+ VLYNQ_CTRL_REG = VLYNQ_CTRL_REG & (~VLYNQ_CTL_INTFIELDS_CLEAR_MASK); -+ -+ /** Or the bits to be set with Control register **/ -+ VLYNQ_CTRL_REG = VLYNQ_CTRL_REG | val; -+ -+ /* initialise local ICB */ -+ if(vlynqInterruptInit(pdev)==VLYNQ_MEMALLOC_FAIL) -+ return VLYNQ_MEMALLOC_FAIL; -+ -+ /* Install handler for local module status interrupts. By default when -+ * local interrupt setting is initialised, the local module status are -+ * enabled and handler hooked up */ -+ if(vlynq_install_isr(pdev, intSetting->map_vector, vlynq_local_module_isr, -+ pdev, NULL, NULL) == VLYNQ_INVALID_ARG) -+ return VLYNQ_INVALID_ARG; -+ } /* end of init local interrupts */ -+ -+ if(options & VLYNQ_INIT_REMOTE_INTERRUPTS ) -+ { -+ /* Configure remote interrupt settings from configuration */ -+ intSetting = &(pdev->remote_irq); -+ -+ /* Map remote module status interrupts to remote interrupt vector*/ -+ val = intSetting->map_vector << VLYNQ_CTL_INTVEC_SHIFT ; -+ /* enable remote module status interrupts */ -+ val |= 0x01 << VLYNQ_CTL_INTEN_SHIFT; -+ -+ if ( intSetting->intLocal == VLYNQ_INT_LOCAL ) -+ { -+ /*set the intLocal bit*/ -+ val |= 0x01 << VLYNQ_CTL_INTLOCAL_SHIFT; -+ } -+ -+ /* Irrespective of whether interrupts are handled locally, program -+ * int2Cfg. Error checking for accidental loop(when intLocal=0 and int2Cfg=1 -+ * i.e remote packets are set intPending register->which will result in -+ * same packet being sent out) has been done already -+ */ -+ -+ if (intSetting->intRemote == VLYNQ_INT_ROOT_ISR) -+ { -+ /* Set the int2Cfg register, so that remote interrupt -+ * packets are written to intPending register */ -+ val |= 0x01 << VLYNQ_CTL_INT2CFG_SHIFT; -+ /* Set intPtr register to point to intPending register */ -+ VLYNQ_R_INT_PTR_REG = VLYNQ_R_INT_PENDING_REG_PTR ; -+ } -+ else -+ { -+ /*set the interrupt pointer register*/ -+ VLYNQ_R_INT_PTR_REG = intSetting->intr_ptr; -+ /* Dont bother to modify int2Cfg as it would be zero */ -+ } -+ -+ if( (intSetting->intLocal == VLYNQ_INT_REMOTE) && -+ (options & VLYNQ_INIT_LOCAL_INTERRUPTS) && -+ (pdev->local_irq.intRemote == VLYNQ_INT_ROOT_ISR) ) -+ { -+ /* Install handler for remote module status interrupts. By default when -+ * remote interrupts are forwarded to local root_isr then remote_module_isr is -+ * enabled and handler hooked up */ -+ if(vlynq_install_isr(pdev,intSetting->map_vector,vlynq_remote_module_isr, -+ pdev, NULL, NULL) == VLYNQ_INVALID_ARG) -+ return VLYNQ_INVALID_ARG; -+ } -+ -+ -+ /** Clear bits related to INT settings in control register **/ -+ VLYNQ_R_CTRL_REG = VLYNQ_R_CTRL_REG & (~VLYNQ_CTL_INTFIELDS_CLEAR_MASK); -+ -+ /** Or the bits to be set with the remote Control register **/ -+ VLYNQ_R_CTRL_REG = VLYNQ_R_CTRL_REG | val; -+ -+ } /* init remote interrupt settings*/ -+ -+ if(options & VLYNQ_INIT_CLEAR_ERRORS ) -+ { -+ /* Clear errors during initialization */ -+ tmp = VLYNQ_STATUS_REG & (VLYNQ_STS_RERROR_MASK | VLYNQ_STS_LERROR_MASK); -+ VLYNQ_STATUS_REG = tmp; -+ tmp = VLYNQ_R_STATUS_REG & (VLYNQ_STS_RERROR_MASK | VLYNQ_STS_LERROR_MASK); -+ VLYNQ_R_STATUS_REG = tmp; -+ } -+ -+ /* clear int status */ -+ val = VLYNQ_INT_STAT_REG; -+ VLYNQ_INT_STAT_REG = val; -+ -+ /* finish initialization */ -+ pdev->state = VLYNQ_DRV_STATE_RUN; -+ VLYNQ_RESETCB( VLYNQ_RESET_INITOK); -+ return VLYNQ_SUCCESS; -+ -+} -+ -+ -+/* ---------------------------------------------------------------------------- -+ * Function : vlynqInterruptInit() -+ * Description: This local function is used to set up the ICB table for the -+ * VLYNQ_STATUS_REG vlynq module. The input parameter "pdev" points the vlynq -+ * device instance whose ICB is allocated. -+ * Return : returns VLYNQ_SUCCESS or vlynq error for failure -+ * ----------------------------------------------------------------------------- -+ */ -+static int vlynqInterruptInit(VLYNQ_DEV *pdev) -+{ -+ int i, numslots; -+ -+ /* Memory allocated statically. -+ * Initialise ICB,free list.Indicate primary slot empty. -+ * Intialise intVector <==> map_vector translation table*/ -+ for(i=0; i < VLYNQ_NUM_INT_BITS; i++) -+ { -+ pdev->pIntrCB[i].isr = NULL; -+ pdev->pIntrCB[i].next = NULL; /*nothing chained */ -+ pdev->vector_map[i] = -1; /* indicates unmapped */ -+ } -+ -+ /* In the ICB slots, [VLYNQ_NUM_INT_BITS i.e 32 to ICB array size) are expansion slots -+ * required only when interrupt chaining/sharing is supported. In case -+ * of chained interrupts the list starts from primary slot and the -+ * additional slots are obtained from the common free area */ -+ -+ /* Initialise freelist */ -+ -+ numslots = VLYNQ_NUM_INT_BITS + VLYNQ_IVR_CHAIN_SLOTS; -+ -+ if (numslots > VLYNQ_NUM_INT_BITS) -+ { -+ pdev->freelist = &(pdev->pIntrCB[VLYNQ_NUM_INT_BITS]); -+ -+ for(i = VLYNQ_NUM_INT_BITS; i < (numslots-1) ; i++) -+ { -+ pdev->pIntrCB[i].next = &(pdev->pIntrCB[i+1]); -+ pdev->pIntrCB[i].isr = NULL; -+ } -+ pdev->pIntrCB[i].next=NULL; /* Indicate end of freelist*/ -+ pdev->pIntrCB[i].isr=NULL; -+ } -+ else -+ { -+ pdev->freelist = NULL; -+ } -+ -+ /** Reset mapping for IV 0-7 **/ -+ VLYNQ_IVR_03TO00_REG = 0; -+ VLYNQ_IVR_07TO04_REG = 0; -+ -+ return VLYNQ_SUCCESS; -+} -+ -+/** remember that hooking up of root ISR handler with the interrupt controller -+ * is not done as a part of this driver. Typically, it must be done after -+ * invoking vlynq_init*/ -+ -+ -+ /* ---------------------------------------------------------------------------- -+ * ISR with the SOC interrupt controller. This ISR typically scans -+ * the Int PENDING/SET register in the VLYNQ module and calls the -+ * appropriate ISR associated with the correponding vector number. -+ * ----------------------------------------------------------------------------- -+ */ -+void vlynq_root_isr(void *arg) -+{ -+ int source; /* Bit position of pending interrupt, start from 0 */ -+ unsigned int interrupts, clrInterrupts; -+ VLYNQ_DEV * pdev; -+ VLYNQ_INTR_CNTRL_ICB *entry; -+ -+ pdev=(VLYNQ_DEV*)(arg); /*obtain the vlynq device pointer*/ -+ -+ interrupts = VLYNQ_INT_STAT_REG; /* Get the list of pending interrupts */ -+ VLYNQ_INT_STAT_REG = interrupts; /* clear the int CR register */ -+ clrInterrupts = interrupts; /* save them for further analysis */ -+ -+ debugPrint("vlynq_root_isr: dev %u. INTCR = 0x%08lx\n", pdev->dev_idx, clrInterrupts,0,0,0,0); -+ -+ /* Scan interrupt bits */ -+ source =0; -+ while( clrInterrupts != 0) -+ { -+ /* test if bit is set? */ -+ if( 0x1ul & clrInterrupts) -+ { -+ entry = &(pdev->pIntrCB[source]); /* Get the ISR entry */ -+ pdev->intCount++; /* update interrupt count */ -+ if(entry->isr != NULL) -+ { -+ do -+ { -+ pdev->isrCount++; /* update isr invocation count */ -+ /* Call the user ISR and update the count for ISR */ -+ entry->isrCount++; -+ entry->isr(entry->arg1, entry->arg2, entry->arg3); -+ if (entry->next == NULL) break; -+ entry = entry->next; -+ -+ } while (entry->isr != NULL); -+ } -+ else -+ { -+ debugPrint(" ISR not installed for vlynq vector:%d\n",source,0,0,0,0,0); -+ } -+ } -+ clrInterrupts >>= 1; /* Next source bit */ -+ ++source; -+ } /* endWhile clrInterrupts != 0 */ -+} -+ -+ -+ /* ---------------------------------------------------------------------------- -+ * Function : vlynq_local__module_isr() -+ * Description: This ISR is attached to the local VLYNQ interrupt vector -+ * by the Vlynq Driver when local interrupts are being handled. i.e. -+ * intLocal=1. This ISR handles local Vlynq module status interrupts only -+ * AS a part of this ISR, user callback in VLYNQ_DEV structure -+ * is invoked. -+ * VLYNQ_DEV is passed as arg1. arg2 and arg3 are unused. -+ * ----------------------------------------------------------------------------- -+ */ -+static void vlynq_local_module_isr(void *arg1,void *arg2, void *arg3) -+{ -+ VLYNQ_REPORT_CB func; -+ unsigned int dwStatRegVal; -+ VLYNQ_DEV * pdev; -+ -+ pdev = (VLYNQ_DEV*) arg1; -+ /* Callback function is read from the device pointer that is passed as an argument */ -+ func = pdev->report_cb; -+ -+ /* read local status register */ -+ dwStatRegVal = VLYNQ_STATUS_REG; -+ -+ /* clear pending events */ -+ VLYNQ_STATUS_REG = dwStatRegVal; -+ -+ /* invoke user callback */ -+ if( func != NULL) -+ func( pdev, VLYNQ_LOCAL_DVC, dwStatRegVal); -+ -+} -+ -+ /* ---------------------------------------------------------------------------- -+ * Function : vlynq_remote_module_isr() -+ * Description: This ISR is attached to the remote VLYNQ interrupt vector -+ * by the Vlynq Driver when remote interrupts are being handled locally. i.e. -+ * intLocal=1. This ISR handles local Vlynq module status interrupts only -+ * AS a part of this ISR, user callback in VLYNQ_DEV structure -+ * is invoked. -+ * The parameters irq,regs ar unused. -+ * ----------------------------------------------------------------------------- -+ */ -+static void vlynq_remote_module_isr(void *arg1,void *arg2, void *arg3) -+{ -+ VLYNQ_REPORT_CB func; -+ unsigned int dwStatRegVal; -+ VLYNQ_DEV * pdev; -+ -+ -+ pdev = (VLYNQ_DEV*) arg1; -+ -+ /* Callback function is read from the device pointer that is passed as an argument */ -+ func = pdev->report_cb; -+ -+ /* read local status register */ -+ dwStatRegVal = VLYNQ_R_STATUS_REG; -+ -+ /* clear pending events */ -+ VLYNQ_R_STATUS_REG = dwStatRegVal; -+ -+ /* invoke user callback */ -+ if( func != NULL) -+ func( pdev, VLYNQ_REMOTE_DVC, dwStatRegVal); -+ -+} -+ -+/* ---------------------------------------------------------------------------- -+ * Function : vlynq_interrupt_get_count() -+ * Description: This function returns the number of times a particular intr -+ * has been invoked. -+ * -+ * It returns 0, if erroneous map_vector is specified or if the corres isr -+ * has not been registered with VLYNQ. -+ */ -+unsigned int vlynq_interrupt_get_count(VLYNQ_DEV *pdev, -+ unsigned int map_vector) -+{ -+ VLYNQ_INTR_CNTRL_ICB *entry; -+ unsigned int count = 0; -+ -+ if (map_vector > (VLYNQ_NUM_INT_BITS-1)) -+ return count; -+ -+ entry = &(pdev->pIntrCB[map_vector]); -+ -+ if (entry) -+ count = entry->isrCount; -+ -+ return (count); -+} -+ -+ -+/* ---------------------------------------------------------------------------- -+ * Function : vlynq_install_isr() -+ * Description: This function installs ISR for Vlynq interrupt vector -+ * bits(in IntPending register). This function should be used only when -+ * Vlynq interrupts are being handled locally(remote may be programmed to send -+ * interrupt packets).Also, the int2cfg should be 1 and the least significant -+ * 8 bits of the Interrupt Pointer Register must point to Interrupt -+ * Pending/Set Register). -+ * If host int2cfg=0 and the Interrupt Pointer register contains -+ * the address of the interrupt set register in the interrupt controller -+ * module of the local device , then the ISR for the remote interrupt must be -+ * directly registered with the Interrupt controller and must not use this API -+ * Note: this function simply installs the ISR in ICB It doesnt modify -+ * any register settings -+ */ -+int -+vlynq_install_isr(VLYNQ_DEV *pdev, -+ unsigned int map_vector, -+ VLYNQ_INTR_CNTRL_ISR isr, -+ void *arg1, void *arg2, void *arg3) -+{ -+ VLYNQ_INTR_CNTRL_ICB *entry; -+ -+ if ( (map_vector > (VLYNQ_NUM_INT_BITS-1)) || (isr == NULL) ) -+ return VLYNQ_INVALID_ARG; -+ -+ entry = &(pdev->pIntrCB[map_vector]); -+ -+ if(entry->isr == NULL) -+ { -+ entry->isr = isr; -+ entry->arg1 = arg1; -+ entry->arg2 = arg2; -+ entry->arg3 = arg3; -+ entry->next = NULL; -+ } -+ else -+ { -+ /** No more empty slots,return error */ -+ if(pdev->freelist == NULL) -+ return VLYNQ_MEMALLOC_FAIL; -+ -+ while(entry->next != NULL) -+ { -+ entry = entry->next; -+ } -+ -+ /* Append new node to the chain */ -+ entry->next = pdev->freelist; -+ /* Remove the appended node from freelist */ -+ pdev->freelist = pdev->freelist->next; -+ entry= entry->next; -+ -+ /*** Set the ICB fields ***/ -+ entry->isr = isr; -+ entry->arg1 = arg1; -+ entry->arg2 = arg2; -+ entry->arg3 = arg3; -+ entry->next = NULL; -+ } -+ -+ return VLYNQ_SUCCESS; -+} -+ -+ -+ -+/* ---------------------------------------------------------------------------- -+ * Function : vlynq_uninstall_isr -+ * Description: This function is used to uninstall a previously -+ * registered ISR. In case of shared/chained interrupts, the -+ * void * arg parameter must uniquely identify the ISR to be -+ * uninstalled. -+ * Note: this function simply uninstalls the ISR in ICB -+ * It doesnt modify any register settings -+ */ -+int -+vlynq_uninstall_isr(VLYNQ_DEV *pdev, -+ unsigned int map_vector, -+ void *arg1, void *arg2, void *arg3) -+{ -+ VLYNQ_INTR_CNTRL_ICB *entry,*temp; -+ -+ if (map_vector > (VLYNQ_NUM_INT_BITS-1)) -+ return VLYNQ_INVALID_ARG; -+ -+ entry = &(pdev->pIntrCB[map_vector]); -+ -+ if(entry->isr == NULL ) -+ return VLYNQ_ISR_NON_EXISTENT; -+ -+ if ( (entry->arg1 == arg1) && (entry->arg2 == arg2) && (entry->arg3 == arg3) ) -+ { -+ if(entry->next == NULL) -+ { -+ entry->isr=NULL; -+ return VLYNQ_SUCCESS; -+ } -+ else -+ { -+ temp = entry->next; -+ /* Copy next node in the chain to prim.slot */ -+ entry->isr = temp->isr; -+ entry->arg1 = temp->arg1; -+ entry->arg2 = temp->arg2; -+ entry->arg3 = temp->arg3; -+ entry->next = temp->next; -+ /* Free the just copied node */ -+ temp->isr = NULL; -+ temp->arg1 = NULL; -+ temp->arg2 = NULL; -+ temp->arg3 = NULL; -+ temp->next = pdev->freelist; -+ pdev->freelist = temp; -+ return VLYNQ_SUCCESS; -+ } -+ } -+ else -+ { -+ temp = entry; -+ while ( (entry = temp->next) != NULL) -+ { -+ if ( (entry->arg1 == arg1) && (entry->arg2 == arg2) && (entry->arg3 == arg3) ) -+ { -+ /* remove node from chain */ -+ temp->next = entry->next; -+ /* Add the removed node to freelist */ -+ entry->isr = NULL; -+ entry->arg1 = NULL; -+ entry->arg2 = NULL; -+ entry->arg3 = NULL; -+ entry->next = pdev->freelist; -+ entry->isrCount = 0; -+ pdev->freelist = entry; -+ return VLYNQ_SUCCESS; -+ } -+ temp = entry; -+ } -+ -+ return VLYNQ_ISR_NON_EXISTENT; -+ } -+} -+ -+ -+ -+ -+/* ---------------------------------------------------------------------------- -+ * function : vlynq_interrupt_vector_set() -+ * description:configures interrupt vector mapping,interrupt type -+ * polarity -all in one go. -+ */ -+int -+vlynq_interrupt_vector_set(VLYNQ_DEV *pdev, /* vlynq device */ -+ unsigned int int_vector, /* int vector on vlynq device */ -+ unsigned int map_vector, /* bit for this interrupt */ -+ VLYNQ_DEV_TYPE dev_type, /* local or remote device */ -+ VLYNQ_INTR_POLARITY pol, /* polarity of interrupt */ -+ VLYNQ_INTR_TYPE type) /* pulsed/level interrupt */ -+{ -+ volatile unsigned int * vecreg; -+ unsigned int val=0; -+ unsigned int bytemask=0XFF; -+ -+ /* use the lower 8 bits of val to set the value , shift it to -+ * appropriate byte position in the ivr and write it to the -+ * corresponding register */ -+ -+ /* validate the number of interrupts supported */ -+ if (int_vector >= VLYNQ_IVR_MAXIVR) -+ return VLYNQ_INVALID_ARG; -+ -+ if(map_vector > (VLYNQ_NUM_INT_BITS - 1) ) -+ return VLYNQ_INVALID_ARG; -+ -+ if (dev_type == VLYNQ_LOCAL_DVC) -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); -+ } -+ else -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); -+ } -+ -+ /* Update the intVector<==> bit position translation table */ -+ pdev->vector_map[map_vector] = int_vector; -+ -+ /* val has been initialised to zero. we only have to turn on appropriate bits*/ -+ if(type == VLYNQ_INTR_PULSED) -+ val |= VLYNQ_IVR_INTTYPE_MASK; -+ -+ if(pol == VLYNQ_INTR_ACTIVE_LOW) -+ val |= VLYNQ_IVR_INTPOL_MASK; -+ -+ val |= map_vector; -+ -+ /** clear the correct byte position and then or val **/ -+ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); -+ -+ /** write to correct byte position in vecreg*/ -+ *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; -+ -+ /* Setting a interrupt vector, leaves the interrupt disabled -+ * which must be enabled subsequently */ -+ -+ return VLYNQ_SUCCESS; -+} -+ -+ -+/* ---------------------------------------------------------------------------- -+ * Function : vlynq_interrupt_vector_cntl() -+ * Description:enables/disable interrupt -+ */ -+int vlynq_interrupt_vector_cntl( VLYNQ_DEV *pdev, -+ unsigned int int_vector, -+ VLYNQ_DEV_TYPE dev_type, -+ unsigned int enable) -+{ -+ volatile unsigned int *vecReg; -+ unsigned int val=0; -+ unsigned int intenMask=0x80; -+ -+ /* validate the number of interrupts supported */ -+ if (int_vector >= VLYNQ_IVR_MAXIVR) -+ return VLYNQ_INVALID_ARG; -+ -+ if (dev_type == VLYNQ_LOCAL_DVC) -+ { -+ vecReg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); -+ } -+ else -+ { -+ vecReg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); -+ } -+ -+ /** Clear the correct byte position and then or val **/ -+ *vecReg = (*vecReg) & ( ~(intenMask << ( (int_vector %4)*8) ) ); -+ -+ if(enable) -+ { -+ val |= VLYNQ_IVR_INTEN_MASK; -+ /** Write to correct byte position in vecReg*/ -+ *vecReg = (*vecReg) | (val << ( (int_vector % 4)*8) ) ; -+ } -+ -+ return VLYNQ_SUCCESS; -+ -+}/* end of function vlynq_interrupt_vector_cntl */ -+ -+ -+ -+/* ---------------------------------------------------------------------------- -+ * Function : vlynq_interrupt_vector_map() -+ * Description:Configures interrupt vector mapping alone -+ */ -+int -+vlynq_interrupt_vector_map( VLYNQ_DEV *pdev, -+ VLYNQ_DEV_TYPE dev_type, -+ unsigned int int_vector, -+ unsigned int map_vector) -+{ -+ volatile unsigned int * vecreg; -+ unsigned int val=0; -+ unsigned int bytemask=0x1f; /* mask to turn off bits corresponding to int vector */ -+ -+ /* use the lower 8 bits of val to set the value , shift it to -+ * appropriate byte position in the ivr and write it to the -+ * corresponding register */ -+ -+ /* validate the number of interrupts supported */ -+ if (int_vector >= VLYNQ_IVR_MAXIVR) -+ return VLYNQ_INVALID_ARG; -+ -+ if(map_vector > (VLYNQ_NUM_INT_BITS - 1) ) -+ return VLYNQ_INVALID_ARG; -+ -+ if (dev_type == VLYNQ_LOCAL_DVC) -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); -+ } -+ else -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); -+ } -+ -+ /* Update the intVector<==> bit position translation table */ -+ pdev->vector_map[map_vector] = int_vector; -+ -+ /** val has been initialised to zero. we only have to turn on -+ * appropriate bits*/ -+ val |= map_vector; -+ -+ /** clear the correct byte position and then or val **/ -+ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); -+ -+ /** write to correct byte position in vecreg*/ -+ *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; -+ -+ return VLYNQ_SUCCESS; -+} -+ -+ -+/* ---------------------------------------------------------------------------- -+ * function : vlynq_interrupt_set_polarity() -+ * description:configures interrupt polarity . -+ */ -+int -+vlynq_interrupt_set_polarity( VLYNQ_DEV *pdev , -+ VLYNQ_DEV_TYPE dev_type, -+ unsigned int map_vector, -+ VLYNQ_INTR_POLARITY pol) -+{ -+ volatile unsigned int * vecreg; -+ int int_vector; -+ unsigned int val=0; -+ unsigned int bytemask=0x20; /** mask to turn off bits corresponding to int polarity */ -+ -+ /* get the int_vector from map_vector */ -+ int_vector = pdev->vector_map[map_vector]; -+ -+ if(int_vector == -1) -+ return VLYNQ_INTVEC_MAP_NOT_FOUND; -+ -+ /* use the lower 8 bits of val to set the value , shift it to -+ * appropriate byte position in the ivr and write it to the -+ * corresponding register */ -+ -+ if (dev_type == VLYNQ_LOCAL_DVC) -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); -+ } -+ else -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); -+ } -+ -+ /* val has been initialised to zero. we only have to turn on -+ * appropriate bits, if need be*/ -+ -+ /** clear the correct byte position and then or val **/ -+ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); -+ -+ if( pol == VLYNQ_INTR_ACTIVE_LOW) -+ { -+ val |= VLYNQ_IVR_INTPOL_MASK; -+ /** write to correct byte position in vecreg*/ -+ *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; -+ } -+ -+ return VLYNQ_SUCCESS; -+} -+ -+int vlynq_interrupt_get_polarity( VLYNQ_DEV *pdev , -+ VLYNQ_DEV_TYPE dev_type, -+ unsigned int map_vector) -+{ -+ volatile unsigned int * vecreg; -+ int int_vector; -+ unsigned int val=0; -+ -+ /* get the int_vector from map_vector */ -+ int_vector = pdev->vector_map[map_vector]; -+ -+ if (map_vector > (VLYNQ_NUM_INT_BITS-1)) -+ return(-1); -+ -+ if(int_vector == -1) -+ return VLYNQ_INTVEC_MAP_NOT_FOUND; -+ -+ /* use the lower 8 bits of val to set the value , shift it to -+ * appropriate byte position in the ivr and write it to the -+ * corresponding register */ -+ -+ if (dev_type == VLYNQ_LOCAL_DVC) -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); -+ } -+ else -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); -+ } -+ -+ /** read the information into val **/ -+ val = (*vecreg) & ((VLYNQ_IVR_INTPOL_MASK << ( (int_vector %4)*8) ) ); -+ -+ return (val ? (VLYNQ_INTR_ACTIVE_LOW) : (VLYNQ_INTR_ACTIVE_HIGH)); -+} -+ -+ -+/* ---------------------------------------------------------------------------- -+ * function : vlynq_interrupt_set_type() -+ * description:configures interrupt type . -+ */ -+int vlynq_interrupt_set_type( VLYNQ_DEV *pdev, -+ VLYNQ_DEV_TYPE dev_type, -+ unsigned int map_vector, -+ VLYNQ_INTR_TYPE type) -+{ -+ volatile unsigned int * vecreg; -+ unsigned int val=0; -+ int int_vector; -+ -+ /** mask to turn off bits corresponding to interrupt type */ -+ unsigned int bytemask=0x40; -+ -+ /* get the int_vector from map_vector */ -+ int_vector = pdev->vector_map[map_vector]; -+ if(int_vector == -1) -+ return VLYNQ_INTVEC_MAP_NOT_FOUND; -+ -+ /* use the lower 8 bits of val to set the value , shift it to -+ * appropriate byte position in the ivr and write it to the -+ * corresponding register */ -+ if (dev_type == VLYNQ_LOCAL_DVC) -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); -+ } -+ else -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); -+ } -+ -+ /** val has been initialised to zero. we only have to turn on -+ * appropriate bits if need be*/ -+ -+ /** clear the correct byte position and then or val **/ -+ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); -+ -+ if( type == VLYNQ_INTR_PULSED) -+ { -+ val |= VLYNQ_IVR_INTTYPE_MASK; -+ /** write to correct byte position in vecreg*/ -+ *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; -+ } -+ -+ return VLYNQ_SUCCESS; -+} -+ -+/* ---------------------------------------------------------------------------- -+ * function : vlynq_interrupt_get_type() -+ * description:returns interrupt type . -+ */ -+int vlynq_interrupt_get_type( VLYNQ_DEV *pdev, VLYNQ_DEV_TYPE dev_type, -+ unsigned int map_vector) -+{ -+ volatile unsigned int * vecreg; -+ unsigned int val=0; -+ int int_vector; -+ -+ if (map_vector > (VLYNQ_NUM_INT_BITS-1)) -+ return(-1); -+ -+ /* get the int_vector from map_vector */ -+ int_vector = pdev->vector_map[map_vector]; -+ if(int_vector == -1) -+ return VLYNQ_INTVEC_MAP_NOT_FOUND; -+ -+ /* use the lower 8 bits of val to set the value , shift it to -+ * appropriate byte position in the ivr and write it to the -+ * corresponding register */ -+ if (dev_type == VLYNQ_LOCAL_DVC) -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); -+ } -+ else -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); -+ } -+ -+ /** Read the correct bit position into val **/ -+ val = (*vecreg) & ((VLYNQ_IVR_INTTYPE_MASK << ( (int_vector %4)*8) ) ); -+ -+ return (val ? (VLYNQ_INTR_PULSED) : (VLYNQ_INTR_LEVEL)); -+} -+ -+/* ---------------------------------------------------------------------------- -+ * function : vlynq_interrupt_enable() -+ * description:Enable interrupt by writing to IVR register. -+ */ -+int vlynq_interrupt_enable( VLYNQ_DEV *pdev, -+ VLYNQ_DEV_TYPE dev_type, -+ unsigned int map_vector) -+{ -+ volatile unsigned int * vecreg; -+ unsigned int val=0; -+ int int_vector; -+ -+ /** mask to turn off bits corresponding to interrupt enable */ -+ unsigned int bytemask=0x80; -+ -+ /* get the int_vector from map_vector */ -+ int_vector = pdev->vector_map[map_vector]; -+ if(int_vector == -1) -+ return VLYNQ_INTVEC_MAP_NOT_FOUND; -+ -+ /* use the lower 8 bits of val to set the value , shift it to -+ * appropriate byte position in the ivr and write it to the -+ * corresponding register */ -+ -+ if (dev_type == VLYNQ_LOCAL_DVC) -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); -+ } -+ else -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); -+ } -+ -+ /** val has been initialised to zero. we only have to turn on -+ * bit corresponding to interrupt enable*/ -+ val |= VLYNQ_IVR_INTEN_MASK; -+ -+ /** clear the correct byte position and then or val **/ -+ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); -+ -+ /** write to correct byte position in vecreg*/ -+ *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; -+ -+ return VLYNQ_SUCCESS; -+} -+ -+ -+/* ---------------------------------------------------------------------------- -+ * function : vlynq_interrupt_disable() -+ * description:Disable interrupt by writing to IVR register. -+ */ -+int -+vlynq_interrupt_disable( VLYNQ_DEV *pdev, -+ VLYNQ_DEV_TYPE dev_type, -+ unsigned int map_vector) -+{ -+ volatile unsigned int * vecreg; -+ int int_vector; -+ -+ /** mask to turn off bits corresponding to interrupt enable */ -+ unsigned int bytemask=0x80; -+ -+ /* get the int_vector from map_vector */ -+ int_vector = pdev->vector_map[map_vector]; -+ if(int_vector == -1) -+ return VLYNQ_INTVEC_MAP_NOT_FOUND; -+ -+ /* use the lower 8 bits of val to set the value , shift it to -+ * appropriate byte position in the ivr and write it to the -+ * corresponding register */ -+ if (dev_type == VLYNQ_LOCAL_DVC) -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); -+ } -+ else -+ { -+ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); -+ } -+ -+ /* We disable the interrupt by simply turning off the bit -+ * corresponding to Interrupt enable. -+ * Clear the interrupt enable bit in the correct byte position **/ -+ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); -+ -+ /* Dont have to set any bit positions */ -+ -+ return VLYNQ_SUCCESS; -+ -+} -+ -+ -+ -+ -diff -urN linux.old/drivers/char/Config.in linux.dev/drivers/char/Config.in ---- linux.old/drivers/char/Config.in 2005-07-22 06:47:42.777975272 +0200 -+++ linux.dev/drivers/char/Config.in 2005-07-22 06:48:54.359093288 +0200 -@@ -192,6 +192,13 @@ - tristate 'Total Impact briQ front panel driver' CONFIG_BRIQ_PANEL - fi - -+if [ "$CONFIG_AR7" = "y" ]; then -+ bool 'VLYNQ support for the TI SOC' CONFIG_AR7_VLYNQ -+ dep_bool 'VLYNQ clock source Internal' CONFIG_VLYNQ_CLK_LOCAL $CONFIG_AR7_VLYNQ -+ -+ define_int CONFIG_AR7_VLYNQ_PORTS 2 -+fi -+ - source drivers/i2c/Config.in - - mainmenu_option next_comment -diff -urN linux.old/drivers/char/Makefile linux.dev/drivers/char/Makefile ---- linux.old/drivers/char/Makefile 2005-07-22 06:47:35.151134728 +0200 -+++ linux.dev/drivers/char/Makefile 2005-07-22 06:32:53.360187328 +0200 -@@ -191,6 +191,13 @@ - endif - - # -+# Texas Intruments VLYNQ driver -+# -+ -+subdir-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq -+obj-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq/avalanche_vlynq.o -+ -+# - # Texas Intruments LED driver - # - obj-$(CONFIG_AR7_LED) += avalanche_led/avalanche_led.o -diff -urN linux.old/include/asm-mips/ar7/vlynq.h linux.dev/include/asm-mips/ar7/vlynq.h ---- linux.old/include/asm-mips/ar7/vlynq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/ar7/vlynq.h 2005-07-22 06:32:53.361187176 +0200 -@@ -0,0 +1,610 @@ -+/*************************************************************************** -+**+----------------------------------------------------------------------+** -+**| **** |** -+**| **** |** -+**| ******o*** |** -+**| ********_///_**** |** -+**| ***** /_//_/ **** |** -+**| ** ** (__/ **** |** -+**| ********* |** -+**| **** |** -+**| *** |** -+**| |** -+**| Copyright (c) 2003 Texas Instruments Incorporated |** -+**| ALL RIGHTS RESERVED |** -+**| |** -+**| Permission is hereby granted to licensees of Texas Instruments |** -+**| Incorporated (TI) products to use this computer program for the sole |** -+**| purpose of implementing a licensee product based on TI products. |** -+**| No other rights to reproduce, use, or disseminate this computer |** -+**| program, whether in part or in whole, are granted. |** -+**| |** -+**| TI makes no representation or warranties with respect to the |** -+**| performance of this computer program, and specifically disclaims |** -+**| any responsibility for any damages, special or consequential, |** -+**| connected with the use of this program. |** -+**| |** -+**+----------------------------------------------------------------------+** -+***************************************************************************/ -+ -+/********************************************************************************* -+ * ------------------------------------------------------------------------------ -+ * Module : vlynq_hal.h -+ * Description : -+ * This header file provides the set of functions exported by the -+ * VLYNQ HAL. This file is included from the SOC specific VLYNQ driver wrapper. -+ * ------------------------------------------------------------------------------ -+ *********************************************************************************/ -+ -+#ifndef _VLYNQ_HAL_H_ -+#define _VLYNQ_HAL_H_ -+ -+/* Enable/Disable debug feature */ -+#undef VLYNQ_DEBUG -+ -+#ifdef VLYNQ_DEBUG /* This needs to be OS abstracted - for testing use vxworks/linux calls */ -+#define debugPrint(format,args...) -+#else -+#define debugPrint(format,args...) -+#endif -+ -+ /* number of VLYNQ memory regions supported */ -+#define VLYNQ_MAX_MEMORY_REGIONS 0x04 -+ -+ /* Max.number of external interrupt inputs supported by VLYNQ module */ -+#define VLYNQ_IVR_MAXIVR 0x08 -+ -+#define VLYNQ_CLK_DIV_MAX 0x08 -+#define VLYNQ_CLK_DIV_MIN 0x01 -+ -+ -+/*** the total number of entries allocated for ICB would be -+ * 32(for 32 bits in IntPending register) + VLYNQ_IVR_CHAIN_SLOTS*/ -+#define VLYNQ_IVR_CHAIN_SLOTS 10 -+ -+ -+/* Error defines */ -+#define VLYNQ_SUCCESS 0 -+ -+#define VLYNQ_ERRCODE_BASE 0 /* Chosen by system */ -+#define VLYNQ_INVALID_ARG -(VLYNQ_ERRCODE_BASE+1) -+#define VLYNQ_INVALID_DRV_STATE -(VLYNQ_ERRCODE_BASE+2) -+#define VLYNQ_INT_CONFIG_ERR -(VLYNQ_ERRCODE_BASE+3) -+#define VLYNQ_LINK_DOWN -(VLYNQ_ERRCODE_BASE+4) -+#define VLYNQ_MEMALLOC_FAIL -(VLYNQ_ERRCODE_BASE+5) -+#define VLYNQ_ISR_NON_EXISTENT -(VLYNQ_ERRCODE_BASE+6) -+#define VLYNQ_INTVEC_MAP_NOT_FOUND -(VLYNQ_ERRCODE_BASE+7) -+ -+/* Vlynq Defines and Macros */ -+ -+#define VLYNQ_NUM_INT_BITS 32 /* 32 bit interrupt staus register */ -+ -+/* Base address of module */ -+#define VLYNQ_BASE (pdev->module_base) -+ -+#define VLYNQ_REMOTE_REGS_OFFSET 0x0080 -+ -+#define VLYNQ_REV_OFFSET 0x0000 -+#define VLYNQ_CTRL_OFFSET 0x0004 -+#define VLYNQ_STATUS_OFFSET 0x0008 -+#define VLYNQ_INT_STAT_OFFSET 0x0010 -+#define VLYNQ_INT_PEND_OFFSET 0x0014 -+#define VLYNQ_INT_PTR_OFFSET 0x0018 -+#define VLYNQ_TXMAP_OFFSET 0x001c -+ -+#define VLYNQ_RX0MAP_SIZE_REG_OFFSET 0x0020 -+#define VLYNQ_RX0MAP_OFFSET_REG_OFFSET 0x0024 -+ -+#define VLYNQ_CHIP_VER_OFFSET 0x0040 -+#define VLYNQ_IVR_REGS_OFFSET 0x0060 -+ -+#define VLYNQ_INT_PENDING_REG_PTR 0x14 -+#define VLYNQ_R_INT_PENDING_REG_PTR VLYNQ_REMOTE_REGS_OFFSET + 0x14 -+ -+#define VLYNQ_REV_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_REV_OFFSET)) -+#define VLYNQ_CTRL_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_CTRL_OFFSET)) -+#define VLYNQ_STATUS_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_STATUS_OFFSET)) -+#define VLYNQ_INT_STAT_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_INT_STAT_OFFSET)) -+#define VLYNQ_INT_PEND_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_INT_PEND_OFFSET)) -+#define VLYNQ_INT_PTR_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_INT_PTR_OFFSET)) -+#define VLYNQ_TXMAP_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_TXMAP_OFFSET)) -+ -+/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ -+#define VLYNQ_RXMAP_SIZE_REG(map) \ -+ *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_RX0MAP_SIZE_REG_OFFSET+( (map-1)<<3))) -+ -+/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ -+#define VLYNQ_RXMAP_OFFSET_REG(map) \ -+ *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_RX0MAP_OFFSET_REG_OFFSET+( (map-1)<<3))) -+ -+#define VLYNQ_CHIP_VER_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_CHIP_VER_OFFSET)) -+ -+/* 0 =< ivr <= 31; currently ivr < VLYNQ_IVR_MAXIVR=8) */ -+#define VLYNQ_IVR_OFFSET(ivr) \ -+ (VLYNQ_BASE + VLYNQ_IVR_REGS_OFFSET +((((unsigned)(ivr)) & 31) & ~3) ) -+ -+#define VLYNQ_IVR_03TO00_REG *((volatile unsigned int*) (VLYNQ_IVR_OFFSET(0)) ) -+#define VLYNQ_IVR_07TO04_REG *((volatile unsigned int*) (VLYNQ_IVR_OFFSET(4)) ) -+/*** Can be extended for 11TO08...31TO28 when all 31 are supported**/ -+ -+#define VLYNQ_IVR_INTEN(ivr) (((unsigned int)(0x80)) << ((((unsigned)(ivr)) % 4) * 8)) -+#define VLYNQ_IVR_INTTYPE(ivr) (((unsigned int)(0x40)) << ((((unsigned)(ivr)) % 4) * 8)) -+#define VLYNQ_IVR_INTPOL(ivr) (((unsigned int)(0x20)) << ((((unsigned)(ivr)) % 4) * 8)) -+#define VLYNQ_IVR_INTVEC(ivr) (((unsigned int)(0x1F)) << ((((unsigned)(ivr)) % 4) * 8)) -+#define VLYNQ_IVR_INTALL(ivr) (((unsigned int)(0xFF)) << ((((unsigned)(ivr)) % 4) * 8)) -+ -+ -+ -+/********************************* -+ * Remote VLYNQ register set * -+ *********************************/ -+ -+#define VLYNQ_R_REV_OFFSET 0x0080 -+#define VLYNQ_R_CTRL_OFFSET 0x0084 -+#define VLYNQ_R_STATUS_OFFSET 0x0088 -+#define VLYNQ_R_INT_STAT_OFFSET 0x0090 -+#define VLYNQ_R_INT_PEND_OFFSET 0x0094 -+#define VLYNQ_R_INT_PTR_OFFSET 0x0098 -+#define VLYNQ_R_TXMAP_OFFSET 0x009c -+ -+#define VLYNQ_R_RX0MAP_SIZE_REG_OFFSET 0x00A0 -+#define VLYNQ_R_RX0MAP_OFFSET_REG_OFFSET 0x00A4 -+ -+#define VLYNQ_R_CHIP_VER_OFFSET 0x00C0 -+#define VLYNQ_R_IVR_REGS_OFFSET 0x00E0 -+ -+#define VLYNQ_R_REV_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_REV_OFFSET)) -+#define VLYNQ_R_CTRL_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_CTRL_OFFSET)) -+#define VLYNQ_R_STATUS_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_STATUS_OFFSET)) -+#define VLYNQ_R_INT_STAT_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_INT_STAT_OFFSET)) -+#define VLYNQ_R_INT_PEND_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_INT_PEND_OFFSET)) -+#define VLYNQ_R_INT_PTR_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_INT_PTR_OFFSET)) -+#define VLYNQ_R_TXMAP_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_TXMAP_OFFSET)) -+ -+/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ -+#define VLYNQ_R_RXMAP_SIZE_REG(map) \ -+ *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_RX0MAP_SIZE_REG_OFFSET + ((map-1)<<3))) -+ -+/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ -+#define VLYNQ_R_RXMAP_OFFSET_REG(map) \ -+ *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_RX0MAP_OFFSET_REG_OFFSET + ((map-1)<<3))) -+ -+#define VLYNQ_R_CHIP_VER_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_CHIP_VER_OFFSET) -+ -+#define VLYNQ_R_IVR_OFFSET(ivr) \ -+ (VLYNQ_BASE + VLYNQ_R_IVR_REGS_OFFSET +((((unsigned)(ivr)) & 31) & ~3)) -+ -+ -+/*** Can be extended for 11TO08...31TO28 when all 31 are supported**/ -+#define VLYNQ_R_IVR_03TO00_REG *((volatile unsigned int*) (VLYNQ_R_IVR_OFFSET(0)) ) -+#define VLYNQ_R_IVR_07TO04_REG *((volatile unsigned int*) (VLYNQ_R_IVR_OFFSET(4)) ) -+ -+ -+/****End of remote register set definition******/ -+ -+ -+/*** Masks for individual register fields ***/ -+ -+#define VLYNQ_MODULE_ID_MASK 0xffff0000 -+#define VLYNQ_MAJOR_REV_MASK 0x0000ff00 -+#define VLYNQ_MINOR_REV_MASK 0x000000ff -+ -+ -+#define VLYNQ_CTL_ILOOP_MASK 0x00000002 -+#define VLYNQ_CTL_INT2CFG_MASK 0x00000080 -+#define VLYNQ_CTL_INTVEC_MASK 0x00001f00 -+#define VLYNQ_CTL_INTEN_MASK 0x00002000 -+#define VLYNQ_CTL_INTLOCAL_MASK 0x00004000 -+#define VLYNQ_CTL_CLKDIR_MASK 0x00008000 -+#define VLYNQ_CTL_CLKDIV_MASK 0x00070000 -+#define VLYNQ_CTL_MODE_MASK 0x00e00000 -+ -+ -+#define VLYNQ_STS_LINK_MASK 0x00000001 /* Link is active */ -+#define VLYNQ_STS_MPEND_MASK 0x00000002 /* Pending master requests */ -+#define VLYNQ_STS_SPEND_MASK 0x00000004 /* Pending slave requests */ -+#define VLYNQ_STS_NFEMPTY0_MASK 0x00000008 /* Master data FIFO not empty */ -+#define VLYNQ_STS_NFEMPTY1_MASK 0x00000010 /* Master command FIFO not empty */ -+#define VLYNQ_STS_NFEMPTY2_MASK 0x00000020 /* Slave data FIFO not empty */ -+#define VLYNQ_STS_NFEMPTY3_MASK 0x00000040 /* Slave command FIFO not empty */ -+#define VLYNQ_STS_LERROR_MASK 0x00000080 /* Local error, w/c */ -+#define VLYNQ_STS_RERROR_MASK 0x00000100 /* remote error w/c */ -+#define VLYNQ_STS_OFLOW_MASK 0x00000200 -+#define VLYNQ_STS_IFLOW_MASK 0x00000400 -+#define VLYNQ_STS_MODESUP_MASK 0x00E00000 /* Highest mode supported */ -+#define VLYNQ_STS_SWIDTH_MASK 0x07000000 /* Used for reading the width of VLYNQ bus */ -+#define VLYNQ_STS_DEBUG_MASK 0xE0000000 -+ -+#define VLYNQ_CTL_INTVEC_SHIFT 0x08 -+#define VLYNQ_CTL_INTEN_SHIFT 0x0D -+#define VLYNQ_CTL_INT2CFG_SHIFT 0x07 -+#define VLYNQ_CTL_INTLOCAL_SHIFT 0x0E -+ -+#define VLYNQ_CTL_INTFIELDS_CLEAR_MASK 0x7F80 -+ -+#define VLYNQ_CHIPVER_DEVREV_MASK 0xffff0000 -+#define VLYNQ_CHIPVER_DEVID_MASK 0x0000ffff -+ -+#define VLYNQ_IVR_INTEN_MASK 0x80 -+#define VLYNQ_IVR_INTTYPE_MASK 0x40 -+#define VLYNQ_IVR_INTPOL_MASK 0x20 -+ -+ -+/**** Helper macros ****/ -+ -+#define VLYNQ_RESETCB(arg) \ -+ if( pdev->reset_cb != NULL) \ -+ { \ -+ (pdev->reset_cb)(pdev, (arg)); \ -+ } -+ -+#define VLYNQ_STATUS_FLD_WIDTH(sts) (((sts) & VLYNQ_STS_SWIDTH_MASK) >> 24 ) -+#define VLYNQ_CTL_INTVEC(x) (((x) & 31) << 8 ) -+ -+#define VLYNQ_INRANGE(x,hi,lo) (((x) <= (hi)) && ((x) >= (lo))) -+#define VLYNQ_OUTRANGE(x,hi,lo) (((x) > (hi)) || ((x) < (lo))) -+ -+#define VLYNQ_ALIGN4(x) (x)=(x)&(~3) -+ -+ -+/************************************* -+ * Enums * -+ *************************************/ -+ -+/* Initialization options define what operations are -+ * undertaken during vlynq module initialization */ -+typedef enum -+{ -+ /* Init host local memory regions.This allows -+ * local host access remote memory regions */ -+ VLYNQ_INIT_LOCAL_MEM_REGIONS = 0x01, -+ /* Init host remote memory regions.This allows -+ * remote device access local memory regions */ -+ VLYNQ_INIT_REMOTE_MEM_REGIONS =0x02, -+ /* Init local interrupt config*/ -+ VLYNQ_INIT_LOCAL_INTERRUPTS =0x04, -+ /* Init remote interrupt config*/ -+ VLYNQ_INIT_REMOTE_INTERRUPTS =0x08, -+ /* Check link during initialization*/ -+ VLYNQ_INIT_CHECK_LINK =0x10, -+ /* configure clock during init */ -+ VLYNQ_INIT_CONFIG_CLOCK =0x20, -+ /* Clear errors during init */ -+ VLYNQ_INIT_CLEAR_ERRORS =0x40, -+ /* All options */ -+ VLYNQ_INIT_PERFORM_ALL =0x7F -+}VLYNQ_INIT_OPTIONS; -+ -+ -+/* VLYNQ_DEV_TYPE identifies local or remote device */ -+typedef enum -+{ -+ VLYNQ_LOCAL_DVC = 0, /* vlynq local device (SOC's vlynq module) */ -+ VLYNQ_REMOTE_DVC = 1 /* vlynq remote device (remote vlynq module) */ -+}VLYNQ_DEV_TYPE; -+ -+ -+/* VLYNQ_CLK_SOURCE identifies the vlynq module clock source */ -+typedef enum -+{ -+ VLYNQ_CLK_SOURCE_NONE = 0, /* do not initialize clock generator*/ -+ VLYNQ_CLK_SOURCE_LOCAL = 1, /* clock is generated by local machine */ -+ VLYNQ_CLK_SOURCE_REMOTE = 2 /* clock is generated by remote machine */ -+}VLYNQ_CLK_SOURCE; -+ -+ -+/* VLYNQ_DRV_STATE indicates the current driver state */ -+typedef enum -+{ -+ VLYNQ_DRV_STATE_UNINIT = 0, /* driver is uninitialized */ -+ VLYNQ_DRV_STATE_ININIT = 1, /* VLYNQ is being initialized */ -+ VLYNQ_DRV_STATE_RUN = 2, /* VLYNQ is running properly */ -+ VLYNQ_DRV_STATE_HOLD = 3, /* driver stopped temporarily */ -+ VLYNQ_DRV_STATE_ERROR = 4 /* driver stopped on unrecoverable error */ -+}VLYNQ_DRV_STATE; -+ -+ -+/* VLYNQ_BUS_WIDTH identifies the vlynq module bus width */ -+typedef enum -+{ -+ VLYNQ_BUS_WIDTH_3 = 3, -+ VLYNQ_BUS_WIDTH_5 = 5, -+ VLYNQ_BUS_WIDTH_7 = 7, -+ VLYNQ_BUS_WIDTH_9 = 9 -+}VLYNQ_BUS_WIDTH; -+ -+ -+/* VLYNQ_LOCAL_INT_CONFIG indicates whether the local vlynq -+ * interrupts are processed by the host or passed on to the -+ * remote device. -+ */ -+typedef enum -+{ -+ VLYNQ_INT_REMOTE = 0, /* Interrupt packets sent to remote, intlocal=0 */ -+ VLYNQ_INT_LOCAL = 1 /* Interrupts are handled locally, intlocal=1 */ -+}VLYNQ_LOCAL_INT_CONFIG; -+ -+ -+/* VLYNQ_REMOTE_INT_CONFIG indicates whether the remote -+ * interrupts are to be handled by the SOC system ISR -+ * or via the vlynq root ISR -+ */ -+typedef enum -+{ -+ VLYNQ_INT_ROOT_ISR = 0, /* remote ints handled via vlynq root ISR */ -+ VLYNQ_INT_SYSTEM_ISR = 1 /* remote ints handled via system ISR */ -+}VLYNQ_REMOTE_INT_CONFIG; -+ -+ -+/* VLYNQ_INTR_POLARITY - vlynq interrupt polarity setting */ -+typedef enum -+{ -+ VLYNQ_INTR_ACTIVE_HIGH = 0, -+ VLYNQ_INTR_ACTIVE_LOW = 1 -+}VLYNQ_INTR_POLARITY; -+ -+ -+/* VLYNQ_INTR_TYPE - vlynq interrupt type */ -+typedef enum -+{ -+ VLYNQ_INTR_LEVEL = 0, -+ VLYNQ_INTR_PULSED = 1 -+}VLYNQ_INTR_TYPE; -+ -+ -+/* VLYNQ_RESET_MODE - vlynq reset mode */ -+typedef enum -+{ -+ VLYNQ_RESET_ASSERT, /* hold device in reset state */ -+ VLYNQ_RESET_DEASSERT, /* release device from reset state */ -+ VLYNQ_RESET_INITFAIL, /* handle the device in case driver initialization fails */ -+ VLYNQ_RESET_LINKESTABLISH, /* handle the device in case driver established link */ -+ VLYNQ_RESET_INITFAIL2, /* Driver initialization failed but VLYNQ link exist. */ -+ VLYNQ_RESET_INITOK /* Driver initialization finished OK. */ -+}VLYNQ_RESET_MODE; -+ -+ -+ -+/************************************* -+ * Typedefs * -+ *************************************/ -+ -+struct VLYNQ_DEV_t; /*forward declaration*/ -+ -+/*--------Function Pointers defintions -----------*/ -+ -+/* prototype for interrupt handler definition */ -+typedef void (*VLYNQ_INTR_CNTRL_ISR)(void *arg1,void *arg2,void *arg3); -+ -+typedef void -+(*VLYNQ_RESET_REMOTE)(struct VLYNQ_DEV_t *pDev, VLYNQ_RESET_MODE mode); -+ -+typedef void -+(*VLYNQ_REPORT_CB)( struct VLYNQ_DEV_t *pDev, /* This VLYNQ */ -+ VLYNQ_DEV_TYPE aSrcDvc, /* Event Cause -local/remote? */ -+ unsigned int dwStatRegVal); /* Value of the relevant status register */ -+ -+ -+/*-------Structure Definitions------------*/ -+ -+typedef struct VLYNQ_MEMORY_MAP_t -+{ -+ unsigned int Txmap; -+ unsigned int RxOffset[VLYNQ_MAX_MEMORY_REGIONS]; -+ unsigned int RxSize[VLYNQ_MAX_MEMORY_REGIONS]; -+}VLYNQ_MEMORY_MAP; -+ -+ -+/**VLYNQ_INTERRUPT_CNTRL - defines the vlynq module interrupt -+ * settings in vlynq Control register */ -+typedef struct VLYNQ_INTERRUPT_CNTRL_t -+{ -+ /* vlynq interrupts handled by host or remote - maps to -+ * intLocal bit in vlynq control register */ -+ VLYNQ_LOCAL_INT_CONFIG intLocal; -+ -+ /* remote interrupts handled by vlynq isr or host system -+ * interrupt controller - maps to the int2Cfg in vlynq -+ * control register */ -+ VLYNQ_REMOTE_INT_CONFIG intRemote; -+ -+ /* bit in pending/set register used for module interrupts*/ -+ unsigned int map_vector; -+ -+ /* used only if remote interrupts are to be handled by system ISR*/ -+ unsigned int intr_ptr; -+ -+}VLYNQ_INTERRUPT_CNTRL; -+ -+ -+/* VLYNQ_INTR_CNTRL_ICB - defines the Interrupt control block which hold -+ * the interrupt dispatch table. The vlynq_root_isr() indexes into this -+ * table to identify the ISR to be invoked -+ */ -+typedef struct VLYNQ_INTR_CNTRL_ICB_t -+{ -+ VLYNQ_INTR_CNTRL_ISR isr; /* Clear errors during initialization */ -+ void *arg1 ; /* Arg 1 for the ISR */ -+ void *arg2 ; /* Arg 2 for the ISR */ -+ void *arg3 ; /* Arg 3 for the ISR */ -+ unsigned int isrCount; /* number of ISR invocations so far */ -+ struct VLYNQ_INTR_CNTRL_ICB_t *next; -+}VLYNQ_INTR_CNTRL_ICB; -+ -+/* overlay of vlynq register set */ -+typedef struct VLYNQ_REG_SET_t -+{ -+ unsigned int revision; /*offset : 0x00 */ -+ unsigned int control; /* 0x04*/ -+ unsigned int status; /* 0x08*/ -+ unsigned int pad1; /* 0x0c*/ -+ unsigned int intStatus; /*0x10*/ -+ unsigned int intPending; /*0x14*/ -+ unsigned int intPtr; /*0x18*/ -+ unsigned int txMap; /*0x1C*/ -+ unsigned int rxSize1; /*0x20*/ -+ unsigned int rxOffset1; /*0x24*/ -+ unsigned int rxSize2; /*0x28*/ -+ unsigned int rxOffset2; /*0x2C*/ -+ unsigned int rxSize3; /*0x30*/ -+ unsigned int rxOffset3; /*0x34*/ -+ unsigned int rxSize4; /*0x38*/ -+ unsigned int rxOffset4; /*0x3C*/ -+ unsigned int chipVersion; /*0x40*/ -+ unsigned int pad2[8]; -+ unsigned int ivr30; /*0x60*/ -+ unsigned int ivr74; /*0x64*/ -+ unsigned int pad3[7]; -+}VLYNQ_REG_SET; -+ -+ -+typedef struct VLYNQ_DEV_t -+{ -+ /** module index:1,2,3... used for debugging purposes */ -+ unsigned int dev_idx; -+ -+ /*VLYNQ module base address */ -+ unsigned int module_base; -+ -+ /* clock source selection */ -+ VLYNQ_CLK_SOURCE clk_source; -+ -+ /* Clock Divider.Val=1 to 8. VLYNQ_clk = VBUSCLK/clk_div */ -+ unsigned int clk_div; -+ -+ /* State of the VLYNQ driver, set to VLYNQ_DRV_STATE_UNINIT, when initializing */ -+ VLYNQ_DRV_STATE state; -+ -+ /* Valid VLYNQ bus width, filled by driver */ -+ VLYNQ_BUS_WIDTH width; -+ -+ /* local memory mapping */ -+ VLYNQ_MEMORY_MAP local_mem; -+ -+ /* remote memory mapping */ -+ VLYNQ_MEMORY_MAP remote_mem; -+ -+ /* Local module interrupt params */ -+ VLYNQ_INTERRUPT_CNTRL local_irq; -+ -+ /* remote module interrupt params */ -+ VLYNQ_INTERRUPT_CNTRL remote_irq; -+ -+ /*** ICB related fields **/ -+ -+ /* Sizeof of ICB = VLYNQ_NUM_INT_BITS(for 32 bits in IntPending) + -+ * expansion slots for shared interrupts*/ -+ VLYNQ_INTR_CNTRL_ICB pIntrCB[VLYNQ_NUM_INT_BITS + VLYNQ_IVR_CHAIN_SLOTS]; -+ VLYNQ_INTR_CNTRL_ICB *freelist; -+ -+ /* table holding mapping between intVector and the bit position the interrupt -+ * is mapped to(mapVector)*/ -+ char vector_map[32]; -+ -+ /* user callback for vlynq events, NULL if unused */ -+ VLYNQ_REPORT_CB report_cb; -+ -+ /* user callback for resetting/realeasing remote device */ -+ VLYNQ_RESET_REMOTE reset_cb; -+ -+ /*** Handles provided for direct access to register set if need be -+ * Must be intialized to point to appropriate address during -+ * vlynq_init */ -+ volatile VLYNQ_REG_SET * local; -+ volatile VLYNQ_REG_SET * remote; -+ -+ unsigned int intCount; /* number of interrupts generated so far */ -+ unsigned int isrCount; /* number of ISR invocations so far */ -+}VLYNQ_DEV; -+ -+ -+typedef struct VLYNQ_ISR_ARGS_t -+{ -+ int irq; -+ void * arg; -+ void * regset; -+}VLYNQ_ISR_ARGS; -+ -+ -+/**************************************** -+ * Function Prototypes * -+ * API exported by generic vlynq driver * -+ ****************************************/ -+/* Initialization function */ -+int vlynq_init( VLYNQ_DEV *pdev, VLYNQ_INIT_OPTIONS options); -+ -+/* Check vlynq link */ -+unsigned int vlynq_link_check( VLYNQ_DEV * pdev); -+ -+/* Set interrupt vector in local or remote device */ -+int vlynq_interrupt_vector_set( VLYNQ_DEV *pdev, -+ unsigned int int_vector, -+ unsigned int map_vector, -+ VLYNQ_DEV_TYPE dev, -+ VLYNQ_INTR_POLARITY pol, -+ VLYNQ_INTR_TYPE type); -+ -+ -+int vlynq_interrupt_vector_cntl( VLYNQ_DEV *pdev, -+ unsigned int int_vector, -+ VLYNQ_DEV_TYPE dev, -+ unsigned int enable); -+ -+unsigned int vlynq_interrupt_get_count( VLYNQ_DEV *pdev, -+ unsigned int map_vector); -+ -+int vlynq_install_isr( VLYNQ_DEV *pdev, -+ unsigned int map_vector, -+ VLYNQ_INTR_CNTRL_ISR isr, -+ void *arg1, void *arg2, void *arg3); -+ -+int vlynq_uninstall_isr( VLYNQ_DEV *pdev, -+ unsigned int map_vector, -+ void *arg1, void *arg2, void *arg3); -+ -+ -+void vlynq_root_isr(void *arg); -+ -+void vlynq_delay(unsigned int clktime); -+ -+/* The following functions, provide better granularity in setting -+ * interrupt parameters. (for better support of linux INT Controller) -+ * Note: The interrupt source is identified by "map_vector"- the bit -+ * position in interrupt status register*/ -+ -+int vlynq_interrupt_vector_map(VLYNQ_DEV * pdev, -+ VLYNQ_DEV_TYPE dev, -+ unsigned int int_vector, -+ unsigned int map_vector); -+ -+int vlynq_interrupt_set_polarity(VLYNQ_DEV * pdev, -+ VLYNQ_DEV_TYPE dev, -+ unsigned int map_vector, -+ VLYNQ_INTR_POLARITY pol); -+ -+int vlynq_interrupt_get_polarity( VLYNQ_DEV *pdev , -+ VLYNQ_DEV_TYPE dev_type, -+ unsigned int map_vector); -+ -+int vlynq_interrupt_set_type(VLYNQ_DEV * pdev, -+ VLYNQ_DEV_TYPE dev, -+ unsigned int map_vector, -+ VLYNQ_INTR_TYPE type); -+ -+int vlynq_interrupt_get_type( VLYNQ_DEV *pdev, -+ VLYNQ_DEV_TYPE dev_type, -+ unsigned int map_vector); -+ -+int vlynq_interrupt_enable(VLYNQ_DEV* pdev, -+ VLYNQ_DEV_TYPE dev, -+ unsigned int map_vector); -+ -+int vlynq_interrupt_disable(VLYNQ_DEV * pdev, -+ VLYNQ_DEV_TYPE dev, -+ unsigned int map_vector); -+ -+ -+ -+ -+ -+#endif /* _VLYNQ_HAL_H_ */ |