add vlynq support
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Thu, 21 Jul 2005 20:40:56 +0000 (20:40 +0000)
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Thu, 21 Jul 2005 20:40:56 +0000 (20:40 +0000)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@1525 3c298f89-4303-0410-b956-a3cf2f4a3e73

target/linux/linux-2.4/config/ar7
target/linux/linux-2.4/patches/ar7/005-vlynq.patch [new file with mode: 0644]

index 5c17d99..4b18ecb 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
@@ -178,6 +178,10 @@ CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
@@ -246,6 +250,10 @@ CONFIG_MTD_AR7_BUSWIDTH=2
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
 # CONFIG_MTD_DOC1000 is not set
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
@@ -428,6 +436,10 @@ CONFIG_ATM=m
 CONFIG_ATM_BR2684=m
 # CONFIG_ATM_BR2684_IPFILTER is not set
 CONFIG_VLAN_8021Q=y
+
+#
+#  
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_DECNET is not set
@@ -494,12 +506,20 @@ CONFIG_IPSEC_NAT_TRAVERSAL=y
 # SCSI support
 #
 CONFIG_SCSI=m
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
 CONFIG_BLK_DEV_SD=m
 CONFIG_SD_EXTRA_DEVS=5
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
 CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
 # CONFIG_SCSI_DEBUG_QUEUES is not set
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
@@ -647,6 +667,10 @@ CONFIG_NET_RADIO=y
 # CONFIG_AIRONET4500_NONCS is not set
 # CONFIG_AIRONET4500_PROC is not set
 # CONFIG_HERMES is not set
+
+#
+# Prism54 PCI/PCMCIA GT/Duette Driver - 802.11(a/b/g)
+#
 # CONFIG_PRISM54 is not set
 # CONFIG_NET_WIRELESS is not set
 
@@ -705,6 +729,9 @@ CONFIG_SERIAL_CONSOLE=y
 CONFIG_MIPS_AVALANCHE_LED=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=128
+CONFIG_AR7_VLYNQ=y
+CONFIG_VLYNQ_CLK_LOCAL=y
+CONFIG_AR7_VLYNQ_PORTS=2
 
 #
 # I2C support
@@ -721,6 +748,14 @@ CONFIG_UNIX98_PTY_COUNT=128
 # Joysticks
 #
 # CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_IPMI_PANIC_EVENT is not set
diff --git a/target/linux/linux-2.4/patches/ar7/005-vlynq.patch b/target/linux/linux-2.4/patches/ar7/005-vlynq.patch
new file mode 100644 (file)
index 0000000..eee70c0
--- /dev/null
@@ -0,0 +1,2332 @@
+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-10 20:50:43.556826000 +0200
++++ linux.dev/drivers/char/Config.in   2005-07-22 06:32:53.359187480 +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-10 20:50:43.556826000 +0200
++++ linux.dev/drivers/char/Makefile    2005-07-22 06:32:53.360187328 +0200
+@@ -191,16 +191,23 @@
+ endif
+ #
++# Texas Intruments VLYNQ driver
++# 
++
++subdir-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq
++obj-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq/avalanche_vlynq.o                                                        
++
++#
+ # Texas Intruments LED driver
+ # 
+-ifeq ($(CONFIG_MIPS_AVALANCHE_LED),y)
+-obj-$(CONFIG_MIPS_AVALANCHE_LED) += avalanche_led/avalanche_led.o
+-subdir-$(CONFIG_MIPS_AVALANCHE_LED) += avalanche_led
++ifeq ($(CONFIG_AR7_LED),y)
++obj-$(CONFIG_AR7_LED) += avalanche_led/avalanche_led.o
++subdir-$(CONFIG_AR7_LED) += avalanche_led
+ endif
+-ifeq ($(CONFIG_MIPS_AVALANCHE_LED),m)
+-obj-$(CONFIG_MIPS_AVALANCHE_LED) += avalanche_led/avalanche_led.o
+-subdir-$(CONFIG_MIPS_AVALANCHE_LED) += avalanche_led
++ifeq ($(CONFIG_AR7_LED),m)
++obj-$(CONFIG_AR7_LED) += avalanche_led/avalanche_led.o
++subdir-$(CONFIG_AR7_LED) += avalanche_led
+ endif
+ obj-$(CONFIG_HIL) += hp_keyb.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_ */