change config name of led driver
[oweals/openwrt.git] / openwrt / target / linux / linux-2.4 / patches / ar7 / 005-vlynq.patch
1 diff -urN linux.old/drivers/char/avalanche_vlynq/Makefile linux.dev/drivers/char/avalanche_vlynq/Makefile
2 --- linux.old/drivers/char/avalanche_vlynq/Makefile     1970-01-01 01:00:00.000000000 +0100
3 +++ linux.dev/drivers/char/avalanche_vlynq/Makefile     2005-07-22 06:32:53.345189608 +0200
4 @@ -0,0 +1,14 @@
5 +#
6 +# Makefile for the linux kernel.
7 +#
8 +# Note! Dependencies are done automagically by 'make dep', which also
9 +# removes any old dependencies. DON'T put your own dependencies here
10 +# unless it's something special (ie not a .c file).
11 +#
12 +# Note 2! The CFLAGS definitions are now in the main makefile...
13 +
14 +O_TARGET := avalanche_vlynq.o
15 +
16 +obj-y    +=  vlynq_drv.o  vlynq_hal.o  vlynq_board.o
17 +
18 +include $(TOPDIR)/Rules.make
19 diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_board.c linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c
20 --- linux.old/drivers/char/avalanche_vlynq/vlynq_board.c        1970-01-01 01:00:00.000000000 +0100
21 +++ linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c        2005-07-22 06:34:39.448059520 +0200
22 @@ -0,0 +1,182 @@
23 +/*
24 + * Jeff Harrell, jharrell@ti.com
25 + * Copyright (C) 2001 Texas Instruments, Inc.  All rights reserved.
26 + *
27 + *  This program is free software; you can distribute it and/or modify it
28 + *  under the terms of the GNU General Public License (Version 2) as
29 + *  published by the Free Software Foundation.
30 + *
31 + *  This program is distributed in the hope it will be useful, but WITHOUT
32 + *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
33 + *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
34 + *  for more details.
35 + *
36 + *  You should have received a copy of the GNU General Public License along
37 + *  with this program; if not, write to the Free Software Foundation, Inc.,
38 + *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
39 + *
40 + * Texas Instruments Sangam specific setup.
41 + */
42 +#include <linux/config.h>
43 +#include <asm/ar7/sangam.h>  
44 +#include <asm/ar7/avalanche_misc.h>  
45 +#include <asm/ar7/vlynq.h>  
46 +   
47 +#define SYS_VLYNQ_LOCAL_INTERRUPT_VECTOR       30      /* MSB - 1 bit */
48 +#define SYS_VLYNQ_REMOTE_INTERRUPT_VECTOR      31      /* MSB bit */
49 +#define SYS_VLYNQ_OPTIONS                      0x7F;   /* all options*/
50 +
51 +/* These defines are board specific */
52 +
53 +
54 +#define VLYNQ0_REMOTE_WINDOW1_OFFSET           (0x0C000000)
55 +#define VLYNQ0_REMOTE_WINDOW1_SIZE             (0x500)
56 +
57 +
58 +#define VLYNQ1_REMOTE_WINDOW1_OFFSET           (0x0C000000)
59 +#define VLYNQ1_REMOTE_WINDOW1_SIZE             (0x500)
60 +
61 +
62 +extern VLYNQ_DEV vlynqDevice0, vlynqDevice1;
63 +int    vlynq_init_status[2] = {0, 0};
64 +static int reset_hack = 1;
65 +
66 +void vlynq_ar7wrd_dev_init()
67 +{
68 +    *(unsigned long*) AVALANCHE_GPIO_ENBL    |= (1<<18);
69 +    vlynq_delay(20000);
70 +    *(unsigned long*) AVALANCHE_GPIO_DIR     &= ~(1<<18);
71 +    vlynq_delay(20000);
72 +    *(unsigned long*) AVALANCHE_GPIO_DATA_OUT&= ~(1<<18);
73 +    vlynq_delay(50000);
74 +    *(unsigned long*) AVALANCHE_GPIO_DATA_OUT|=  (1<<18);
75 +    vlynq_delay(50000);
76 +
77 +    /* Initialize the MIPS host vlynq driver for a given vlynq interface */
78 +    vlynqDevice0.dev_idx = 0;                  /* first vlynq module - this parameter is for reference only */
79 +    vlynqDevice0.module_base = AVALANCHE_LOW_VLYNQ_CONTROL_BASE;       /*  vlynq0 module base address */
80 +
81 +#if defined(CONFIG_VLYNQ_CLK_LOCAL)
82 +    vlynqDevice0.clk_source = VLYNQ_CLK_SOURCE_LOCAL;   
83 +#else
84 +    vlynqDevice0.clk_source = VLYNQ_CLK_SOURCE_REMOTE;   
85 +#endif
86 +    vlynqDevice0.clk_div = 0x01;                       /* board/hardware specific */
87 +    vlynqDevice0.state =  VLYNQ_DRV_STATE_UNINIT;      /* uninitialized module */
88 +
89 +    /* Populate vlynqDevice0.local_mem & Vlynq0.remote_mem based on system configuration */ 
90 +    /*Local memory configuration */
91 +
92 +                /* Demiurg : not good !*/
93 +#if 0
94 +    vlynqDevice0.local_mem.Txmap= AVALANCHE_LOW_VLYNQ_MEM_MAP_BASE & ~(0xc0000000) ; /* physical address */
95 +    vlynqDevice0.remote_mem.RxOffset[0]= VLYNQ0_REMOTE_WINDOW1_OFFSET; /* This is specific to the board on the other end */
96 +    vlynqDevice0.remote_mem.RxSize[0]=VLYNQ0_REMOTE_WINDOW1_SIZE;
97 +#endif
98 +
99 +                /* Demiurg : This is how it should be ! */
100 +                vlynqDevice0.local_mem.Txmap = PHYSADDR(AVALANCHE_LOW_VLYNQ_MEM_MAP_BASE);
101 +#define VLYNQ_ACX111_MEM_OFFSET     0xC0000000  /* Physical address of ACX111 memory */
102 +#define VLYNQ_ACX111_MEM_SIZE       0x00040000  /* Total size of the ACX111 memory   */
103 +#define VLYNQ_ACX111_REG_OFFSET     0xF0000000  /* PHYS_ADDR of ACX111 control registers   */
104 +#define VLYNQ_ACX111_REG_SIZE       0x00022000  /* Size of ACX111 registers area, MAC+PHY  */
105 +#define ACX111_VL1_REMOTE_SIZE 0x1000000
106 +                vlynqDevice0.remote_mem.RxOffset[0]  =  VLYNQ_ACX111_MEM_OFFSET;
107 +                vlynqDevice0.remote_mem.RxSize[0]    =  VLYNQ_ACX111_MEM_SIZE  ;
108 +                vlynqDevice0.remote_mem.RxOffset[1]  =  VLYNQ_ACX111_REG_OFFSET;
109 +                vlynqDevice0.remote_mem.RxSize[1]    =  VLYNQ_ACX111_REG_SIZE  ;
110 +                vlynqDevice0.remote_mem.Txmap        =  0;
111 +                vlynqDevice0.local_mem.RxOffset[0]   =  AVALANCHE_SDRAM_BASE;
112 +                vlynqDevice0.local_mem.RxSize[0]     =  ACX111_VL1_REMOTE_SIZE;
113 +
114 +
115 +    /* Local interrupt configuration */
116 +    vlynqDevice0.local_irq.intLocal = VLYNQ_INT_LOCAL;         /* Host handles vlynq interrupts*/
117 +    vlynqDevice0.local_irq.intRemote = VLYNQ_INT_ROOT_ISR;     /* vlynq root isr used */
118 +    vlynqDevice0.local_irq.map_vector = SYS_VLYNQ_LOCAL_INTERRUPT_VECTOR;
119 +    vlynqDevice0.local_irq.intr_ptr = 0; /* Since remote interrupts part of vlynq root isr this is unused */
120 +
121 +    /* Remote interrupt configuration */
122 +    vlynqDevice0.remote_irq.intLocal = VLYNQ_INT_REMOTE;       /* MIPS handles interrupts */
123 +    vlynqDevice0.remote_irq.intRemote = VLYNQ_INT_ROOT_ISR;    /* Not significant since MIPS handles interrupts */
124 +    vlynqDevice0.remote_irq.map_vector = SYS_VLYNQ_REMOTE_INTERRUPT_VECTOR;
125 +    vlynqDevice0. remote_irq.intr_ptr = AVALANCHE_INTC_BASE; /* Not significant since MIPS handles interrupts */
126 +
127 +     if(reset_hack != 1)
128 +       printk("About to re-init the VLYNQ.\n");
129 +
130 +    if(vlynq_init(&vlynqDevice0,VLYNQ_INIT_PERFORM_ALL)== 0)
131 +    {
132 +        /* Suraj added the following to keep the 1130 going. */
133 +        vlynq_interrupt_vector_set(&vlynqDevice0, 0 /* intr vector line running into 1130 vlynq */,
134 +                                   0 /* intr mapped onto the interrupt register on remote vlynq and this vlynq */,
135 +                                   VLYNQ_REMOTE_DVC, 0 /* polarity active high */, 0 /* interrupt Level triggered */);
136 +
137 +        /* System wide interrupt is 80 for 1130, please note. */
138 +        vlynq_init_status[0] = 1;
139 +        reset_hack = 2;
140 +    }
141 +    else
142 +    {
143 +        if(reset_hack == 1)
144 +            printk("VLYNQ INIT FAILED: Please try cold reboot. \n");
145 +        else
146 +            printk("Failed to initialize the VLYNQ interface at insmod.\n");
147 +
148 +    }
149 +}
150 +
151 +void  vlynq_dev_init(void)
152 +{
153 +    volatile unsigned int *reset_base = (unsigned int *) AVALANCHE_RESET_CONTROL_BASE;
154 +
155 +    *reset_base &= ~((1 << AVALANCHE_LOW_VLYNQ_RESET_BIT)); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT)); */
156 +
157 +    vlynq_delay(20000);
158 +
159 +    /* Bring vlynq out of reset if not already done */
160 +    *reset_base |= (1 << AVALANCHE_LOW_VLYNQ_RESET_BIT); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT); */
161 +    vlynq_delay(20000); /* Allowing sufficient time to VLYNQ to settle down.*/
162 +
163 +    vlynq_ar7wrd_dev_init( );
164 +
165 +}
166 +
167 +/* This function is board specific and should be ported for each board. */
168 +void remote_vlynq_dev_reset_ctrl(unsigned int module_reset_bit,
169 +                                 AVALANCHE_RESET_CTRL_T reset_ctrl)
170 +{
171 +    if(module_reset_bit >= 32)
172 +        return;
173 +
174 +    switch(module_reset_bit)
175 +    {
176 +        case 0:
177 +            if(OUT_OF_RESET == reset_ctrl)
178 +            {
179 +                if(reset_hack) return;
180 +
181 +                vlynq_delay(20000);
182 +                printk("Un-resetting the remote device.\n");
183 +                vlynq_dev_init();
184 +                printk("Re-initialized the VLYNQ.\n");
185 +                reset_hack = 2;
186 +            }
187 +            else if(IN_RESET == reset_ctrl)
188 +            {
189 +                *(unsigned long*) AVALANCHE_GPIO_DATA_OUT &= ~(1<<18);
190 +
191 +                vlynq_delay(20000);
192 +                printk("Resetting the remote device.\n");
193 +                reset_hack = 0;
194 +            }
195 +            else
196 +                ;
197 +        break;
198 +
199 +        default:
200 +        break;
201 +
202 +    }
203 +}
204 +
205 diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c
206 --- linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c  1970-01-01 01:00:00.000000000 +0100
207 +++ linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c  2005-07-22 06:32:53.345189608 +0200
208 @@ -0,0 +1,242 @@
209 +/******************************************************************************
210 + * FILE PURPOSE:    Vlynq Linux Device Driver Source
211 + ******************************************************************************
212 + * FILE NAME:       vlynq_drv.c
213 + *
214 + * DESCRIPTION:     Vlynq Linux Device Driver Source
215 + *
216 + * REVISION HISTORY:
217 + *
218 + * Date           Description                       Author
219 + *-----------------------------------------------------------------------------
220 + * 17 July 2003   Initial Creation                  Anant Gole
221 + * 17 Dec  2003   Updates                           Sharath Kumar
222 + *
223 + * (C) Copyright 2003, Texas Instruments, Inc
224 + *******************************************************************************/
225
226 +#include <linux/config.h>
227 +#include <linux/init.h>
228 +#include <linux/module.h>
229 +#include <linux/sched.h>
230 +#include <linux/miscdevice.h>
231 +#include <linux/smp_lock.h>
232 +#include <linux/delay.h>
233 +#include <linux/proc_fs.h>
234 +#include <linux/capability.h>
235 +#include <asm/ar7/avalanche_intc.h>
236 +#include <asm/ar7/sangam.h>
237 +#include <asm/ar7/vlynq.h>
238 +
239 +
240 +#define    TI_VLYNQ_VERSION                 "0.2"
241 +
242 +/* debug on ? */
243 +#define VLYNQ_DEBUG 
244 +
245 +/* Macro for debug and error printf's */
246 +#ifdef VLYNQ_DEBUG
247 +#define DBGPRINT  printk
248 +#else
249 +#define DBGPRINT(x)  
250 +#endif
251 +
252 +#define ERRPRINT  printk
253 +
254 +/* Define the max vlynq ports this driver will support. 
255 +   Device name strings are statically added here */
256 +#define MAX_VLYNQ_PORTS 2
257 +
258 +
259 +/* Type define for VLYNQ private structure */
260 +typedef struct vlynqPriv{
261 +    int irq;
262 +    VLYNQ_DEV *vlynqDevice;
263 +}VLYNQ_PRIV;
264 +
265 +extern int vlynq_init_status[2];
266 +
267 +/* Extern Global variable for vlynq devices used in initialization of the vlynq device
268 + * These variables need to be populated/initialized by the system as part of initialization
269 + * process. The vlynq enumerator can run at initialization and populate these globals
270 + */
271 +
272 +VLYNQ_DEV vlynqDevice0;
273 +VLYNQ_DEV vlynqDevice1;
274 +
275 +/* Defining dummy macro AVALANCHE_HIGH_VLYNQ_INT to take
276 + * care of compilation in case of single vlynq device 
277 + */
278 +
279 +#ifndef AVALANCHE_HIGH_VLYNQ_INT
280 +#define  AVALANCHE_HIGH_VLYNQ_INT 0
281 +#endif
282 +
283 +
284 +
285 +/* vlynq private object */
286 +VLYNQ_PRIV vlynq_priv[CONFIG_AR7_VLYNQ_PORTS] = {
287 +    { LNXINTNUM(AVALANCHE_LOW_VLYNQ_INT),&vlynqDevice0},
288 +    { LNXINTNUM(AVALANCHE_HIGH_VLYNQ_INT),&vlynqDevice1},
289 +};
290 +
291 +extern void vlynq_dev_init(void);
292 +
293 +
294 +/* =================================== all the operations */
295 +
296 +static int
297 +vlynq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
298 +{
299 +    return 0;
300 +}
301 +
302 +static struct file_operations vlynq_fops = {
303 +    owner:      THIS_MODULE,
304 +    ioctl:      vlynq_ioctl,
305 +};
306 +
307 +/* Vlynq device object */
308 +static struct miscdevice vlynq_dev [MAX_VLYNQ_PORTS] = {
309 +    { MISC_DYNAMIC_MINOR , "vlynq0", &vlynq_fops },
310 +    { MISC_DYNAMIC_MINOR , "vlynq1", &vlynq_fops },
311 +};
312 +
313 +
314 +/* Proc read function */
315 +static int
316 +vlynq_read_link_proc(char *buf, char **start, off_t offset, int count, int *eof, void *unused)
317 +{
318 +    int instance;
319 +    int len = 0;
320
321 +    len += sprintf(buf +len,"VLYNQ Devices : %d\n",CONFIG_AR7_VLYNQ_PORTS);
322 +
323 +    for(instance =0;instance < CONFIG_AR7_VLYNQ_PORTS;instance++)
324 +    {
325 +        int link_state;
326 +        char *link_msg[] = {" DOWN "," UP "};
327 +       
328 +        if(vlynq_init_status[instance] == 0)
329 +            link_state = 0; 
330 +
331 +        else if (vlynq_link_check(vlynq_priv[instance].vlynqDevice))
332 +            link_state = 1;
333 +
334 +        else
335 +            link_state = 0;    
336 +
337 +        len += sprintf(buf + len, "VLYNQ %d: Link state: %s\n",instance,link_msg[link_state]);
338 +
339 +    }
340 +    /* Print info about vlynq device 1 */
341 +   
342 +    return len;
343 +}
344 +
345 +
346 +/* Proc function to display driver version */                                                                       
347 +static int                                                                                     
348 +vlynq_read_ver_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data)        
349 +{                                                                                              
350 +       int instance;                                                                              
351 +       int len=0;                                                                                 
352 +                                                                                               
353 +       len += sprintf(buf +len,"\nTI Linux VLYNQ Driver Version %s\n",TI_VLYNQ_VERSION);         
354 +       return len;                                                                                
355 +}                                                                                              
356 +
357 +
358 +
359 +
360 +/* Wrapper for vlynq ISR */
361 +static void lnx_vlynq_root_isr(int irq, void * arg, struct pt_regs *regs)
362 +{
363 +   vlynq_root_isr(arg);
364 +}
365 +
366 +/* =================================== init and cleanup */
367 +
368 +int vlynq_init_module(void)
369 +{
370 +    int ret;
371 +    int unit = 0;
372 +    int instance_count = CONFIG_AR7_VLYNQ_PORTS;
373 +    volatile int *ptr;
374 +
375 +    vlynq_dev_init();
376 +
377 +    DBGPRINT("Vlynq CONFIG_AR7_VLYNQ_PORTS=%d\n", CONFIG_AR7_VLYNQ_PORTS);
378 +    /* If num of configured vlynq ports > supported by driver return error */
379 +    if (instance_count > MAX_VLYNQ_PORTS)
380 +    {
381 +        ERRPRINT("ERROR: vlynq_init_module(): Max %d supported\n", MAX_VLYNQ_PORTS);
382 +        return (-1);
383 +    }
384 +
385 +    /* register the misc device */
386 +    for (unit = 0; unit < CONFIG_AR7_VLYNQ_PORTS; unit++)
387 +    {
388 +        ret = misc_register(&vlynq_dev[unit]);
389 +
390 +        if(ret < 0)
391 +        {
392 +            ERRPRINT("ERROR:Could not register vlynq device:%d\n",unit);
393 +            continue;
394 +        }
395 +        else 
396 +            DBGPRINT("Vlynq Device %s registered with minor no %d as misc device. Result=%d\n", 
397 +                vlynq_dev[unit].name, vlynq_dev[unit].minor, ret);
398 +#if 0
399 +            
400 +        DBGPRINT("Calling vlynq init\n");
401 +
402 +        /* Read the global variable for VLYNQ device structure and initialize vlynq driver */
403 +        ret = vlynq_init(vlynq_priv[unit].vlynqDevice,VLYNQ_INIT_PERFORM_ALL );
404 +#endif
405 +
406 +        if(vlynq_init_status[unit] == 0)
407 +        {
408 +            printk("VLYNQ %d : init failed\n",unit); 
409 +            continue;
410 +        }
411 +         
412 +        /* Check link before proceeding */
413 +        if (!vlynq_link_check(vlynq_priv[unit].vlynqDevice))
414 +        {
415 +           DBGPRINT("\nError: Vlynq link not available.trying once before  Exiting");
416 +        }
417 +        else
418 +        {
419 +            DBGPRINT("Vlynq instance:%d Link UP\n",unit);
420 +        
421 +            /* Install the vlynq local root ISR */
422 +           request_irq(vlynq_priv[unit].irq,lnx_vlynq_root_isr,0,vlynq_dev[unit].name,vlynq_priv[unit].vlynqDevice);
423 +        } 
424 +    }
425 +
426 +    /* Creating proc entry for the devices */
427 +    create_proc_read_entry("avalanche/vlynq_link", 0, NULL, vlynq_read_link_proc, NULL);
428 +    create_proc_read_entry("avalanche/vlynq_ver", 0, NULL, vlynq_read_ver_proc, NULL);
429 +  
430 +    return 0;
431 +}
432 +
433 +void vlynq_cleanup_module(void)
434 +{
435 +    int unit = 0;
436 +    
437 +    for (unit = 0; unit < CONFIG_AR7_VLYNQ_PORTS; unit++)
438 +    {
439 +        DBGPRINT("vlynq_cleanup_module(): Unregistring misc device %s\n",vlynq_dev[unit].name);
440 +        misc_deregister(&vlynq_dev[unit]);
441 +    }
442 +
443 +    remove_proc_entry("avalanche/vlynq_link", NULL);
444 +    remove_proc_entry("avalanche/vlynq_ver", NULL);
445 +}
446 +
447 +
448 +module_init(vlynq_init_module);
449 +module_exit(vlynq_cleanup_module);
450 +
451 diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c
452 --- linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c  1970-01-01 01:00:00.000000000 +0100
453 +++ linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c  2005-07-22 06:32:53.359187480 +0200
454 @@ -0,0 +1,1214 @@
455 +/***************************************************************************
456 +**+----------------------------------------------------------------------+**
457 +**|                                ****                                  |**
458 +**|                                ****                                  |**
459 +**|                                ******o***                            |**
460 +**|                          ********_///_****                           |**
461 +**|                           ***** /_//_/ ****                          |**
462 +**|                            ** ** (__/ ****                           |**
463 +**|                                *********                             |**
464 +**|                                 ****                                 |**
465 +**|                                  ***                                 |**
466 +**|                                                                      |**
467 +**|     Copyright (c) 2003 Texas Instruments Incorporated                |**
468 +**|                        ALL RIGHTS RESERVED                           |**
469 +**|                                                                      |**
470 +**| Permission is hereby granted to licensees of Texas Instruments       |**
471 +**| Incorporated (TI) products to use this computer program for the sole |**
472 +**| purpose of implementing a licensee product based on TI products.     |**
473 +**| No other rights to reproduce, use, or disseminate this computer      |**
474 +**| program, whether in part or in whole, are granted.                   |**
475 +**|                                                                      |**
476 +**| TI makes no representation or warranties with respect to the         |**
477 +**| performance of this computer program, and specifically disclaims     |**
478 +**| any responsibility for any damages, special or consequential,        |**
479 +**| connected with the use of this program.                              |**
480 +**|                                                                      |**
481 +**+----------------------------------------------------------------------+**
482 +***************************************************************************/
483 +
484 +/***************************************************************************
485 + *  ------------------------------------------------------------------------------
486 + *   Module      : vlynq_hal.c
487 + *   Description : This file implements VLYNQ HAL API.
488 + *  ------------------------------------------------------------------------------
489 + ***************************************************************************/
490 +
491 +#include <linux/stddef.h>
492 +#include <linux/types.h>
493 +#include <asm/ar7/vlynq.h>
494 +
495 +/**** Local Function prototypes *******/
496 +static int vlynqInterruptInit(VLYNQ_DEV *pdev);
497 +static void  vlynq_configClock(VLYNQ_DEV  *pdev);
498 +
499 +/*** Second argument must be explicitly type casted to 
500 + * (VLYNQ_DEV*) inside the following functions */
501 +static void vlynq_local_module_isr(void *arg1, void *arg2, void *arg3);
502 +static void vlynq_remote_module_isr(void *arg1, void *arg2, void *arg3);
503 +
504 +
505 +volatile int vlynq_delay_value = 0;
506 +
507 +/* Code adopted from original vlynq driver */
508 +void vlynq_delay(unsigned int clktime)
509 +{
510 +    int i = 0;
511 +    volatile int    *ptr = &vlynq_delay_value;
512 +    *ptr = 0;
513 +
514 +    /* We are assuming that the each cycle takes about 
515 +     * 23 assembly instructions. */
516 +    for(i = 0; i < (clktime + 23)/23; i++)
517 +    {
518 +        *ptr = *ptr + 1;
519 +    }
520 +}
521 +
522 +
523 +/* ----------------------------------------------------------------------------
524 + *  Function : vlynq_configClock()
525 + *  Description: Configures clock settings based on input parameters
526 + *  Adapted from original vlyna driver from Cable
527 + */
528 +static void vlynq_configClock(VLYNQ_DEV * pdev)
529 +{
530 +    unsigned int tmp;
531 +
532 +    switch( pdev->clk_source)
533 +    {
534 +        case VLYNQ_CLK_SOURCE_LOCAL:  /* we output the clock, clk_div in range [1..8]. */
535 +            tmp = ((pdev->clk_div - 1) << 16) |  VLYNQ_CTL_CLKDIR_MASK ;
536 +            VLYNQ_CTRL_REG = tmp;
537 +            VLYNQ_R_CTRL_REG = 0ul;
538 +            break;
539 +        case VLYNQ_CLK_SOURCE_REMOTE: /* we need to set the clock pin as input */
540 +            VLYNQ_CTRL_REG = 0ul;
541 +            tmp = ((pdev->clk_div - 1) << 16) |  VLYNQ_CTL_CLKDIR_MASK ;
542 +            VLYNQ_R_CTRL_REG = tmp;
543 +            break;
544 +        default:   /* do nothing about the clock, but clear other bits. */
545 +            tmp = ~(VLYNQ_CTL_CLKDIR_MASK | VLYNQ_CTL_CLKDIV_MASK);
546 +            VLYNQ_CTRL_REG &= tmp;
547 +            break;
548 +   }
549 +}
550 +
551 + /* ----------------------------------------------------------------------------
552 + *  Function : vlynq_link_check()
553 + *  Description: This function checks the current VLYNQ for a link.
554 + *  An arbitrary amount of time is allowed for the link to come up .
555 + *  Returns 0 for "no link / failure " and 1 for "link available".
556 + * -----------------------------------------------------------------------------
557 + */
558 +unsigned int vlynq_link_check( VLYNQ_DEV * pdev)
559 +{
560 +    /*sleep for 64 cycles, allow link to come up*/
561 +    vlynq_delay(64);  
562 +      
563 +    /* check status register return OK if link is found. */
564 +    if (VLYNQ_STATUS_REG & VLYNQ_STS_LINK_MASK) 
565 +    {
566 +        return 1;   /* Link Available */
567 +    }
568 +    else
569 +    {
570 +        return 0;   /* Link Failure */
571 +    }
572 +}
573 +
574 +/* ----------------------------------------------------------------------------
575 + *  Function : vlynq_init()
576 + *  Description: Initialization function accepting paramaters for VLYNQ module
577 + *  initialization. The Options bitmap decides what operations are performed
578 + *  as a part of initialization. The Input parameters  are obtained through the
579 + *  sub fields of VLYNQ_DEV structure.
580 + */
581 +
582 +int vlynq_init(VLYNQ_DEV *pdev, VLYNQ_INIT_OPTIONS options)
583 +{
584 +    unsigned int map;
585 +    unsigned int val=0,cnt,tmp;
586 +    unsigned int counter=0;
587 +    VLYNQ_INTERRUPT_CNTRL *intSetting=NULL;
588 +
589 +    /* validate arguments */
590 +    if( VLYNQ_OUTRANGE(pdev->clk_source, VLYNQ_CLK_SOURCE_REMOTE, VLYNQ_CLK_SOURCE_NONE) || 
591 +        VLYNQ_OUTRANGE(pdev->clk_div, 8, 1) )
592 +    {
593 +      return VLYNQ_INVALID_ARG;
594 +    }
595 +   
596 +    /** perform all sanity checks first **/
597 +    if(pdev->state != VLYNQ_DRV_STATE_UNINIT)
598 +        return VLYNQ_INVALID_DRV_STATE;
599 +
600 +    /** Initialize local and remote register set addresses- additional
601 +     * provision to access the registers directly if need be */
602 +    pdev->local = (VLYNQ_REG_SET*)pdev->module_base;
603 +    pdev->remote = (VLYNQ_REG_SET*) (pdev->module_base + VLYNQ_REMOTE_REGS_OFFSET);
604 +
605 +    /* Detect faulty int configuration that might induce int pkt looping */
606 +    if ( (options  & VLYNQ_INIT_LOCAL_INTERRUPTS) && (options & VLYNQ_INIT_REMOTE_INTERRUPTS) )
607 +    {
608 +        /* case when both local and remote are configured */
609 +        if((pdev->local_irq.intLocal== VLYNQ_INT_REMOTE )  /* interrupts transfered to remote from local */
610 +        && (pdev->remote_irq.intLocal== VLYNQ_INT_REMOTE)  /* interrupts transfered from remote to local */
611 +        && ((pdev->local_irq.intRemote == VLYNQ_INT_ROOT_ISR) || (pdev->remote_irq.intRemote == VLYNQ_INT_ROOT_ISR)) )
612 +        {
613 +            return (VLYNQ_INT_CONFIG_ERR); 
614 +        }
615 +    }
616 +
617 +    pdev->state = VLYNQ_DRV_STATE_ININIT;
618 +    pdev->intCount = 0;
619 +    pdev->isrCount = 0;
620 +
621 +    /*** Its assumed that the vlynq module  has been brought out of reset
622 +     * before invocation of vlynq_init. Since, this operation is board specific
623 +     * it must be handled outside this generic driver */
624 +   
625 +    /* Assert reset the remote device, call reset_cb,
626 +     * reset CB holds Reset according to the device needs. */
627 +    VLYNQ_RESETCB(VLYNQ_RESET_ASSERT);
628 +
629 +    /* Handle VLYNQ clock, HW default (Sense On Reset) is
630 +     * usually input for all the devices. */        
631 +    if (options & VLYNQ_INIT_CONFIG_CLOCK)
632 +    {
633 +        vlynq_configClock(pdev);
634 +    }
635
636 +    /* Call reset_cb again. It will release the remote device 
637 +     * from reset, and wait for a while. */
638 +    VLYNQ_RESETCB(VLYNQ_RESET_DEASSERT);
639 +
640 +    if(options & VLYNQ_INIT_CHECK_LINK )
641 +    {
642 +        /* Check for link up during initialization*/
643 +       while( counter < 25 )
644 +       {
645 +       /* loop around giving a chance for link status to settle down */
646 +       counter++;
647 +        if(vlynq_link_check(pdev))
648 +        {
649 +           /* Link is up exit loop*/
650 +          break;
651 +        }
652 +
653 +       vlynq_delay(4000);
654 +       }/*end of while counter loop */
655 +
656 +        if(!vlynq_link_check(pdev))
657 +        {
658 +            /* Handle this case as abort */
659 +            pdev->state = VLYNQ_DRV_STATE_ERROR;
660 +            VLYNQ_RESETCB( VLYNQ_RESET_INITFAIL);
661 +            return VLYNQ_LINK_DOWN;
662 +        }/* end of if not vlynq_link_check conditional block */
663 +      
664 +    }/*end of if options & VLYNQ_INIT_CHECK_LINK conditional block */
665 +
666 +
667 +    if (options & VLYNQ_INIT_LOCAL_MEM_REGIONS)
668 +    {
669 +        /* Initialise local memory regions . This initialization lets
670 +         * the local host access remote device memory regions*/   
671 +        int i; 
672 +
673 +        /* configure the VLYNQ portal window to a PHYSICAL
674 +         * address of the local CPU */
675 +        VLYNQ_ALIGN4(pdev->local_mem.Txmap);
676 +        VLYNQ_TXMAP_REG = (pdev->local_mem.Txmap); 
677 +        
678 +        /*This code assumes input parameter is itself a physical address */
679 +        for(i=0; i < VLYNQ_MAX_MEMORY_REGIONS ; i++)
680 +        {
681 +            /* Physical address on the remote */
682 +            map = i+1;
683 +            VLYNQ_R_RXMAP_SIZE_REG(map) =  0;
684 +            if( pdev->remote_mem.RxSize[i])
685 +            {
686 +                VLYNQ_ALIGN4(pdev->remote_mem.RxOffset[i]);            
687 +                VLYNQ_ALIGN4(pdev->remote_mem.RxSize[i]);
688 +                VLYNQ_R_RXMAP_OFFSET_REG(map) = pdev->remote_mem.RxOffset[i];
689 +                VLYNQ_R_RXMAP_SIZE_REG(map) = pdev->remote_mem.RxSize[i];
690 +            }
691 +        }
692 +    }
693 +
694 +    if(options & VLYNQ_INIT_REMOTE_MEM_REGIONS )
695 +    {
696 +        int i;
697 +
698 +        /* Initialise remote memory regions. This initialization lets remote
699 +         * device access local host memory regions. It configures the VLYNQ portal
700 +         * window to a PHYSICAL address of the remote */
701 +        VLYNQ_ALIGN4(pdev->remote_mem.Txmap);            
702 +        VLYNQ_R_TXMAP_REG = pdev->remote_mem.Txmap;
703 +       
704 +        for( i=0; i<VLYNQ_MAX_MEMORY_REGIONS; i++)
705 +        {
706 +            /* Physical address on the local */
707 +            map = i+1;
708 +            VLYNQ_RXMAP_SIZE_REG(map) =  0;
709 +            if( pdev->local_mem.RxSize[i])
710 +            {
711 +                VLYNQ_ALIGN4(pdev->local_mem.RxOffset[i]);            
712 +                VLYNQ_ALIGN4(pdev->local_mem.RxSize[i]);
713 +                VLYNQ_RXMAP_OFFSET_REG(map) =  (pdev->local_mem.RxOffset[i]);
714 +                VLYNQ_RXMAP_SIZE_REG(map) =  (pdev->local_mem.RxSize[i]);
715 +            }
716 +        }
717 +    }
718 +
719 +    /* Adapted from original vlynq driver from cable - Calculate VLYNQ bus width */
720 +    pdev->width = 3 +  VLYNQ_STATUS_FLD_WIDTH(VLYNQ_STATUS_REG) 
721 +                  + VLYNQ_STATUS_FLD_WIDTH(VLYNQ_R_STATUS_REG);
722 +   
723 +    /* chance to initialize the device, e.g. to boost VLYNQ 
724 +     * clock by modifying pdev->clk_div or and verify the width. */
725 +    VLYNQ_RESETCB(VLYNQ_RESET_LINKESTABLISH);
726 +
727 +    /* Handle VLYNQ clock, HW default (Sense On Reset) is
728 +     * usually input for all the devices. */
729 +    if(options & VLYNQ_INIT_CONFIG_CLOCK )
730 +    {
731 +        vlynq_configClock(pdev);
732 +    }
733 +
734 +    /* last check for link*/
735 +    if(options & VLYNQ_INIT_CHECK_LINK )
736 +    {
737 +     /* Final Check for link during initialization*/
738 +       while( counter < 25 )
739 +       {
740 +       /* loop around giving a chance for link status to settle down */
741 +       counter++;
742 +        if(vlynq_link_check(pdev))
743 +        {
744 +           /* Link is up exit loop*/
745 +          break;
746 +        }
747 +
748 +       vlynq_delay(4000);
749 +       }/*end of while counter loop */
750 +
751 +        if(!vlynq_link_check(pdev))
752 +        {
753 +            /* Handle this case as abort */
754 +            pdev->state = VLYNQ_DRV_STATE_ERROR;
755 +            VLYNQ_RESETCB( VLYNQ_RESET_INITFAIL);
756 +            return VLYNQ_LINK_DOWN;
757 +        }/* end of if not vlynq_link_check conditional block */
758 +        
759 +    } /* end of if options & VLYNQ_INIT_CHECK_LINK */
760 +
761 +    if(options & VLYNQ_INIT_LOCAL_INTERRUPTS )
762 +    {
763 +        /* Configure local interrupt settings */
764 +        intSetting = &(pdev->local_irq);
765 +
766 +        /* Map local module status interrupts to interrupt vector*/
767 +        val = intSetting->map_vector << VLYNQ_CTL_INTVEC_SHIFT ;
768 +      
769 +        /* enable local module status interrupts */
770 +        val |= 0x01 << VLYNQ_CTL_INTEN_SHIFT;
771 +      
772 +        if ( intSetting->intLocal == VLYNQ_INT_LOCAL )
773 +        {
774 +            /*set the intLocal bit*/
775 +            val |= 0x01 << VLYNQ_CTL_INTLOCAL_SHIFT;
776 +        }
777 +      
778 +        /* Irrespective of whether interrupts are handled locally, program
779 +         * int2Cfg. Error checking for accidental loop(when intLocal=0 and int2Cfg=1
780 +         * i.e remote packets are set intPending register->which will result in 
781 +         * same packet being sent out) has been done already
782 +         */
783 +      
784 +        if (intSetting->intRemote == VLYNQ_INT_ROOT_ISR) 
785 +        {
786 +            /* Set the int2Cfg register, so that remote interrupt
787 +             * packets are written to intPending register */
788 +            val |= 0x01 << VLYNQ_CTL_INT2CFG_SHIFT;
789 +    
790 +            /* Set intPtr register to point to intPending register */
791 +            VLYNQ_INT_PTR_REG = VLYNQ_INT_PENDING_REG_PTR ;
792 +        }
793 +        else
794 +        {
795 +            /*set the interrupt pointer register*/
796 +            VLYNQ_INT_PTR_REG = intSetting->intr_ptr;
797 +            /* Dont bother to modify int2Cfg as it would be zero */
798 +        }
799 +
800 +        /** Clear bits related to INT settings in control register **/
801 +        VLYNQ_CTRL_REG = VLYNQ_CTRL_REG & (~VLYNQ_CTL_INTFIELDS_CLEAR_MASK);
802 +      
803 +        /** Or the bits to be set with Control register **/
804 +        VLYNQ_CTRL_REG = VLYNQ_CTRL_REG | val;
805 +
806 +        /* initialise local ICB */          
807 +        if(vlynqInterruptInit(pdev)==VLYNQ_MEMALLOC_FAIL)
808 +            return VLYNQ_MEMALLOC_FAIL;   
809 +
810 +        /* Install handler for local module status interrupts. By default when 
811 +         * local interrupt setting is initialised, the local module status are 
812 +         * enabled and handler hooked up */
813 +        if(vlynq_install_isr(pdev, intSetting->map_vector, vlynq_local_module_isr, 
814 +                             pdev, NULL, NULL) == VLYNQ_INVALID_ARG)
815 +            return VLYNQ_INVALID_ARG;
816 +    } /* end of init local interrupts */
817 +
818 +    if(options & VLYNQ_INIT_REMOTE_INTERRUPTS )
819 +    {
820 +        /* Configure remote interrupt settings from configuration */          
821 +        intSetting = &(pdev->remote_irq);
822 +
823 +        /* Map remote module status interrupts to remote interrupt vector*/
824 +        val = intSetting->map_vector << VLYNQ_CTL_INTVEC_SHIFT ;
825 +        /* enable remote module status interrupts */
826 +        val |= 0x01 << VLYNQ_CTL_INTEN_SHIFT;
827 +      
828 +        if ( intSetting->intLocal == VLYNQ_INT_LOCAL )
829 +        {
830 +            /*set the intLocal bit*/
831 +            val |= 0x01 << VLYNQ_CTL_INTLOCAL_SHIFT;
832 +        }
833 +
834 +        /* Irrespective of whether interrupts are handled locally, program
835 +         * int2Cfg. Error checking for accidental loop(when intLocal=0 and int2Cfg=1
836 +         * i.e remote packets are set intPending register->which will result in 
837 +         * same packet being sent out) has been done already
838 +        */ 
839 +
840 +        if (intSetting->intRemote == VLYNQ_INT_ROOT_ISR) 
841 +        {
842 +            /* Set the int2Cfg register, so that remote interrupt
843 +             * packets are written to intPending register */
844 +            val |= 0x01 << VLYNQ_CTL_INT2CFG_SHIFT;
845 +            /* Set intPtr register to point to intPending register */
846 +            VLYNQ_R_INT_PTR_REG = VLYNQ_R_INT_PENDING_REG_PTR ;
847 +        }
848 +        else
849 +        {
850 +            /*set the interrupt pointer register*/
851 +            VLYNQ_R_INT_PTR_REG = intSetting->intr_ptr;
852 +            /* Dont bother to modify int2Cfg as it would be zero */
853 +        }
854 +    
855 +        if( (intSetting->intLocal == VLYNQ_INT_REMOTE) && 
856 +            (options & VLYNQ_INIT_LOCAL_INTERRUPTS) &&
857 +            (pdev->local_irq.intRemote == VLYNQ_INT_ROOT_ISR) )
858 +        {
859 +            /* Install handler for remote module status interrupts. By default when 
860 +             * remote interrupts are forwarded to local root_isr then remote_module_isr is
861 +             * enabled and handler hooked up */
862 +            if(vlynq_install_isr(pdev,intSetting->map_vector,vlynq_remote_module_isr,
863 +                                 pdev, NULL, NULL) == VLYNQ_INVALID_ARG)
864 +                return VLYNQ_INVALID_ARG;
865 +        }
866 +
867 +         
868 +        /** Clear bits related to INT settings in control register **/
869 +        VLYNQ_R_CTRL_REG = VLYNQ_R_CTRL_REG & (~VLYNQ_CTL_INTFIELDS_CLEAR_MASK);
870 +      
871 +        /** Or the bits to be set with the remote Control register **/
872 +        VLYNQ_R_CTRL_REG = VLYNQ_R_CTRL_REG | val;
873 +         
874 +    } /* init remote interrupt settings*/
875 +
876 +    if(options & VLYNQ_INIT_CLEAR_ERRORS )
877 +    {
878 +        /* Clear errors during initialization */
879 +        tmp = VLYNQ_STATUS_REG  & (VLYNQ_STS_RERROR_MASK | VLYNQ_STS_LERROR_MASK);
880 +        VLYNQ_STATUS_REG = tmp;
881 +        tmp = VLYNQ_R_STATUS_REG & (VLYNQ_STS_RERROR_MASK | VLYNQ_STS_LERROR_MASK);
882 +        VLYNQ_R_STATUS_REG = tmp;
883 +    } 
884 +
885 +    /* clear int status */
886 +    val = VLYNQ_INT_STAT_REG;
887 +    VLYNQ_INT_STAT_REG = val;
888 +    
889 +    /* finish initialization */
890 +    pdev->state = VLYNQ_DRV_STATE_RUN;
891 +    VLYNQ_RESETCB( VLYNQ_RESET_INITOK);
892 +    return VLYNQ_SUCCESS;
893 +
894 +}
895 +
896 +
897 +/* ----------------------------------------------------------------------------
898 + *  Function : vlynqInterruptInit()
899 + *  Description: This local function is used to set up the ICB table for the 
900 + *  VLYNQ_STATUS_REG vlynq module. The input parameter "pdev" points the vlynq
901 + *  device instance whose ICB is allocated.
902 + *  Return : returns VLYNQ_SUCCESS or vlynq error for failure
903 + * -----------------------------------------------------------------------------
904 + */
905 +static int vlynqInterruptInit(VLYNQ_DEV *pdev)
906 +{
907 +    int i, numslots;
908 +
909 +    /* Memory allocated statically.
910 +     * Initialise ICB,free list.Indicate primary slot empty.
911 +     * Intialise intVector <==> map_vector translation table*/
912 +    for(i=0; i < VLYNQ_NUM_INT_BITS; i++)
913 +    {
914 +        pdev->pIntrCB[i].isr = NULL;  
915 +        pdev->pIntrCB[i].next = NULL; /*nothing chained */
916 +        pdev->vector_map[i] = -1;   /* indicates unmapped  */
917 +    }
918 +
919 +    /* In the ICB slots, [VLYNQ_NUM_INT_BITS i.e 32 to ICB array size) are expansion slots
920 +     * required only when interrupt chaining/sharing is supported. In case
921 +     * of chained interrupts the list starts from primary slot and the
922 +     * additional slots are obtained from the common free area */
923 +
924 +    /* Initialise freelist */
925 +
926 +    numslots = VLYNQ_NUM_INT_BITS + VLYNQ_IVR_CHAIN_SLOTS;
927 +    
928 +    if (numslots > VLYNQ_NUM_INT_BITS)
929 +    {
930 +        pdev->freelist = &(pdev->pIntrCB[VLYNQ_NUM_INT_BITS]);
931 +        
932 +        for(i = VLYNQ_NUM_INT_BITS; i < (numslots-1) ; i++)
933 +        {
934 +            pdev->pIntrCB[i].next = &(pdev->pIntrCB[i+1]);
935 +            pdev->pIntrCB[i].isr = NULL;
936 +        }
937 +        pdev->pIntrCB[i].next=NULL; /* Indicate end of freelist*/
938 +        pdev->pIntrCB[i].isr=NULL;
939 +    }  
940 +    else
941 +    {   
942 +        pdev->freelist = NULL;
943 +    }
944 +
945 +    /** Reset mapping for IV 0-7 **/
946 +    VLYNQ_IVR_03TO00_REG = 0;
947 +    VLYNQ_IVR_07TO04_REG = 0;
948 +
949 +    return VLYNQ_SUCCESS;
950 +}
951 +
952 +/** remember that hooking up of root ISR handler with the interrupt controller 
953 + *  is not done as a part of this driver. Typically, it must be done after
954 + *  invoking vlynq_init*/
955 +
956 +
957 + /* ----------------------------------------------------------------------------
958 + *  ISR with the SOC interrupt controller. This ISR typically scans
959 + *  the Int PENDING/SET register in the VLYNQ module and calls the
960 + *  appropriate ISR associated with the correponding vector number.
961 + * -----------------------------------------------------------------------------
962 + */
963 +void vlynq_root_isr(void *arg)
964 +{
965 +    int    source;  /* Bit position of pending interrupt, start from 0 */
966 +    unsigned int interrupts, clrInterrupts;
967 +    VLYNQ_DEV * pdev;
968 +    VLYNQ_INTR_CNTRL_ICB *entry;
969 +
970 +    pdev=(VLYNQ_DEV*)(arg);          /*obtain the vlynq device pointer*/
971
972 +    interrupts =  VLYNQ_INT_STAT_REG; /* Get the list of pending interrupts */
973 +    VLYNQ_INT_STAT_REG = interrupts; /* clear the int CR register */
974 +    clrInterrupts = interrupts;      /* save them for further analysis */
975 +
976 +    debugPrint("vlynq_root_isr: dev %u. INTCR = 0x%08lx\n", pdev->dev_idx, clrInterrupts,0,0,0,0);
977 +
978 +    /* Scan interrupt bits */
979 +    source =0;
980 +    while( clrInterrupts != 0)
981 +    {
982 +        /* test if bit is set? */
983 +        if( 0x1ul & clrInterrupts)
984 +        {   
985 +            entry = &(pdev->pIntrCB[source]);   /* Get the ISR entry */
986 +            pdev->intCount++;                   /* update interrupt count */    
987 +            if(entry->isr != NULL)
988 +            {
989 +                do 
990 +                {
991 +                    pdev->isrCount++;   /* update isr invocation count */    
992 +                    /* Call the user ISR and update the count for ISR */
993 +                   entry->isrCount++;   
994 +                    entry->isr(entry->arg1, entry->arg2, entry->arg3);
995 +                    if (entry->next == NULL) break;
996 +                    entry = entry->next;
997 +
998 +                } while (entry->isr != NULL);
999 +            }
1000 +            else
1001 +            {   
1002 +                debugPrint(" ISR not installed for vlynq vector:%d\n",source,0,0,0,0,0);
1003 +            }
1004 +        }
1005 +        clrInterrupts >>= 1;    /* Next source bit */
1006 +        ++source;
1007 +    } /* endWhile clrInterrupts != 0 */
1008 +}
1009 +
1010 +
1011 + /* ----------------------------------------------------------------------------
1012 + *  Function : vlynq_local__module_isr()
1013 + *  Description: This ISR is attached to the local VLYNQ interrupt vector
1014 + *  by the Vlynq Driver when local interrupts are being handled. i.e.
1015 + *  intLocal=1. This ISR handles local Vlynq module status interrupts only
1016 + *  AS a part of this ISR, user callback in VLYNQ_DEV structure
1017 + *  is invoked.
1018 + *  VLYNQ_DEV is passed as arg1. arg2 and arg3 are unused.
1019 + * -----------------------------------------------------------------------------
1020 + */
1021 +static void vlynq_local_module_isr(void *arg1,void *arg2, void *arg3)
1022 +{
1023 +    VLYNQ_REPORT_CB func;
1024 +    unsigned int dwStatRegVal;
1025 +    VLYNQ_DEV * pdev;
1026 +
1027 +    pdev = (VLYNQ_DEV*) arg1;
1028 +    /* Callback function is read from the device pointer that is passed as an argument */
1029 +    func = pdev->report_cb;
1030 +
1031 +    /* read local status register */
1032 +    dwStatRegVal = VLYNQ_STATUS_REG;
1033 +
1034 +    /* clear pending events */
1035 +    VLYNQ_STATUS_REG = dwStatRegVal;
1036 +   
1037 +    /* invoke user callback */
1038 +    if( func != NULL)
1039 +        func( pdev, VLYNQ_LOCAL_DVC, dwStatRegVal);
1040 +
1041 +}
1042 +
1043 + /* ----------------------------------------------------------------------------
1044 + *  Function : vlynq_remote_module_isr()
1045 + *  Description: This ISR is attached to the remote VLYNQ interrupt vector
1046 + *  by the Vlynq Driver when remote interrupts are being handled locally. i.e.
1047 + *  intLocal=1. This ISR handles local Vlynq module status interrupts only
1048 + *  AS a part of this ISR, user callback in VLYNQ_DEV structure
1049 + *  is invoked.
1050 + *  The parameters  irq,regs ar unused.
1051 + * -----------------------------------------------------------------------------
1052 + */
1053 +static void vlynq_remote_module_isr(void *arg1,void *arg2, void *arg3)
1054 +{
1055 +    VLYNQ_REPORT_CB func;
1056 +    unsigned int dwStatRegVal;
1057 +    VLYNQ_DEV * pdev;
1058 +
1059 +   
1060 +    pdev = (VLYNQ_DEV*) arg1;
1061 +   
1062 +    /* Callback function is read from the device pointer that is passed as an argument */
1063 +   func = pdev->report_cb;
1064 +
1065 +    /* read local status register */
1066 +    dwStatRegVal = VLYNQ_R_STATUS_REG;
1067 +
1068 +    /* clear pending events */
1069 +    VLYNQ_R_STATUS_REG = dwStatRegVal;
1070 +
1071 +    /* invoke user callback */
1072 +    if( func != NULL)
1073 +        func( pdev, VLYNQ_REMOTE_DVC, dwStatRegVal);
1074 +
1075 +}
1076 +
1077 +/* ----------------------------------------------------------------------------
1078 + *  Function : vlynq_interrupt_get_count()
1079 + *  Description: This function returns the number of times a particular intr
1080 + *  has been invoked. 
1081 + *
1082 + *  It returns 0, if erroneous map_vector is specified or if the corres isr 
1083 + *  has not been registered with VLYNQ.
1084 + */
1085 +unsigned int vlynq_interrupt_get_count(VLYNQ_DEV *pdev,
1086 +                                       unsigned int map_vector)
1087 +{
1088 +    VLYNQ_INTR_CNTRL_ICB *entry;
1089 +    unsigned int count = 0;
1090 +
1091 +    if (map_vector > (VLYNQ_NUM_INT_BITS-1)) 
1092 +        return count;
1093 +   
1094 +    entry = &(pdev->pIntrCB[map_vector]);
1095 +
1096 +    if (entry)
1097 +        count = entry->isrCount;
1098 +
1099 +    return (count);
1100 +}
1101 +
1102 +
1103 +/* ----------------------------------------------------------------------------
1104 + *  Function : vlynq_install_isr()
1105 + *  Description: This function installs ISR for Vlynq interrupt vector
1106 + *  bits(in IntPending register). This function should be used only when 
1107 + *  Vlynq interrupts are being handled locally(remote may be programmed to send
1108 + *  interrupt packets).Also, the int2cfg should be 1 and the least significant
1109 + *  8 bits of the Interrupt Pointer Register must point to Interrupt 
1110 + *  Pending/Set Register).
1111 + *  If host int2cfg=0 and the Interrupt Pointer register contains 
1112 + *  the address of the interrupt set register in the interrupt controller 
1113 + *  module of the local device , then the ISR for the remote interrupt must be 
1114 + *  directly registered with the Interrupt controller and must not use this API
1115 + *  Note: this function simply installs the ISR in ICB It doesnt modify
1116 + *  any register settings
1117 + */
1118 +int 
1119 +vlynq_install_isr(VLYNQ_DEV *pdev,
1120 +                  unsigned int map_vector,
1121 +                  VLYNQ_INTR_CNTRL_ISR isr,
1122 +                  void *arg1, void *arg2, void *arg3)
1123 +{
1124 +    VLYNQ_INTR_CNTRL_ICB *entry;
1125 +
1126 +    if ( (map_vector > (VLYNQ_NUM_INT_BITS-1)) || (isr == NULL) ) 
1127 +        return VLYNQ_INVALID_ARG;
1128 +   
1129 +    entry = &(pdev->pIntrCB[map_vector]);
1130 +
1131 +    if(entry->isr == NULL)
1132 +    {
1133 +        entry->isr = isr;
1134 +        entry->arg1 = arg1;
1135 +        entry->arg2 = arg2;
1136 +        entry->arg3 = arg3;
1137 +        entry->next = NULL;
1138 +    }
1139 +    else
1140 +    {
1141 +        /** No more empty slots,return error */
1142 +        if(pdev->freelist == NULL)
1143 +            return VLYNQ_MEMALLOC_FAIL;
1144 +        
1145 +        while(entry->next != NULL)
1146 +        {
1147 +            entry = entry->next;
1148 +        }
1149 +
1150 +        /* Append new node to the chain */
1151 +        entry->next = pdev->freelist;   
1152 +        /* Remove the appended node from freelist */
1153 +        pdev->freelist = pdev->freelist->next;  
1154 +        entry= entry->next;
1155 +         
1156 +        /*** Set the ICB fields ***/
1157 +        entry->isr = isr;
1158 +        entry->arg1 = arg1;
1159 +        entry->arg2 = arg2;
1160 +        entry->arg3 = arg3;
1161 +        entry->next = NULL;
1162 +    }
1163 +   
1164 +    return VLYNQ_SUCCESS;
1165 +}
1166 +
1167 +
1168 +
1169 +/* ----------------------------------------------------------------------------
1170 + *  Function : vlynq_uninstall_isr
1171 + *  Description: This function is used to uninstall a previously
1172 + *  registered ISR. In case of shared/chained interrupts, the 
1173 + *  void * arg parameter must uniquely identify the ISR to be
1174 + *  uninstalled.
1175 + *  Note: this function simply uninstalls the ISR in ICB
1176 + *  It doesnt modify any register settings
1177 + */
1178 +int 
1179 +vlynq_uninstall_isr(VLYNQ_DEV *pdev,
1180 +                    unsigned int map_vector,
1181 +                    void *arg1, void *arg2, void *arg3) 
1182 +{
1183 +    VLYNQ_INTR_CNTRL_ICB *entry,*temp;
1184 +
1185 +    if (map_vector > (VLYNQ_NUM_INT_BITS-1)) 
1186 +        return VLYNQ_INVALID_ARG;
1187 +   
1188 +    entry = &(pdev->pIntrCB[map_vector]);
1189 +
1190 +    if(entry->isr == NULL ) 
1191 +        return VLYNQ_ISR_NON_EXISTENT;
1192 +
1193 +    if ( (entry->arg1 == arg1) && (entry->arg2 == arg2) && (entry->arg3 == arg3) )
1194 +    {
1195 +        if(entry->next == NULL)
1196 +        {
1197 +            entry->isr=NULL;
1198 +            return VLYNQ_SUCCESS;
1199 +        }
1200 +        else
1201 +        {
1202 +            temp =  entry->next;
1203 +            /* Copy next node in the chain to prim.slot */
1204 +            entry->isr = temp->isr;
1205 +            entry->arg1 = temp->arg1;
1206 +            entry->arg2 = temp->arg2;
1207 +            entry->arg3 = temp->arg3;
1208 +            entry->next = temp->next;
1209 +            /* Free the just copied node */
1210 +            temp->isr = NULL;
1211 +            temp->arg1 = NULL;
1212 +            temp->arg2 = NULL;
1213 +            temp->arg3 = NULL;
1214 +            temp->next = pdev->freelist;
1215 +            pdev->freelist = temp;
1216 +            return VLYNQ_SUCCESS;
1217 +        }
1218 +    }
1219 +    else
1220 +    {
1221 +        temp = entry;
1222 +        while ( (entry = temp->next) != NULL)
1223 +        {
1224 +            if ( (entry->arg1 == arg1) && (entry->arg2 == arg2) && (entry->arg3 == arg3) )
1225 +            {
1226 +                /* remove node from chain */
1227 +                temp->next = entry->next; 
1228 +                /* Add the removed node to freelist */
1229 +                entry->isr = NULL;
1230 +                entry->arg1 = NULL;
1231 +                entry->arg2 = NULL;
1232 +                entry->arg3 = NULL;
1233 +                entry->next = pdev->freelist;
1234 +                entry->isrCount = 0;
1235 +                pdev->freelist  = entry;
1236 +                return VLYNQ_SUCCESS;
1237 +            }
1238 +            temp = entry;
1239 +        }
1240 +    
1241 +        return VLYNQ_ISR_NON_EXISTENT;
1242 +    }
1243 +}
1244 +
1245 +
1246 +
1247 +
1248 +/* ----------------------------------------------------------------------------
1249 + *  function : vlynq_interrupt_vector_set()
1250 + *  description:configures interrupt vector mapping,interrupt type
1251 + *  polarity -all in one go.
1252 + */
1253 +int 
1254 +vlynq_interrupt_vector_set(VLYNQ_DEV *pdev,                 /* vlynq device */
1255 +                           unsigned int int_vector,               /* int vector on vlynq device */
1256 +                           unsigned int map_vector,               /* bit for this interrupt */
1257 +                           VLYNQ_DEV_TYPE dev_type,         /* local or remote device */
1258 +                           VLYNQ_INTR_POLARITY pol,         /* polarity of interrupt */
1259 +                           VLYNQ_INTR_TYPE type)            /* pulsed/level interrupt */
1260 +{
1261 +    volatile unsigned int * vecreg;
1262 +    unsigned int val=0;
1263 +    unsigned int bytemask=0XFF;
1264 +
1265 +    /* use the lower 8 bits of val to set the value , shift it to 
1266 +     * appropriate byte position in the ivr and write it to the 
1267 +     * corresponding register */
1268 +
1269 +    /* validate the number of interrupts supported */
1270 +    if (int_vector >= VLYNQ_IVR_MAXIVR) 
1271 +        return VLYNQ_INVALID_ARG;
1272 +        
1273 +    if(map_vector > (VLYNQ_NUM_INT_BITS - 1) ) 
1274 +        return VLYNQ_INVALID_ARG;
1275 +
1276 +    if (dev_type == VLYNQ_LOCAL_DVC)
1277 +    {
1278 +        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector));
1279 +    }
1280 +    else
1281 +    {
1282 +        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));  
1283 +    }
1284 +
1285 +    /* Update the intVector<==> bit position translation table */
1286 +    pdev->vector_map[map_vector] = int_vector;
1287 +
1288 +    /* val has been initialised to zero. we only have to turn on appropriate bits*/
1289 +    if(type == VLYNQ_INTR_PULSED)
1290 +        val |= VLYNQ_IVR_INTTYPE_MASK;
1291 +        
1292 +    if(pol == VLYNQ_INTR_ACTIVE_LOW)
1293 +        val |= VLYNQ_IVR_INTPOL_MASK;
1294 +
1295 +    val |= map_vector;
1296 +
1297 +    /** clear the correct byte position and then or val **/
1298 +    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) );
1299 +
1300 +    /** write to correct byte position in vecreg*/
1301 +    *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ;
1302 +
1303 +    /* Setting a interrupt vector, leaves the interrupt disabled 
1304 +     * which  must be enabled subsequently */
1305 +
1306 +    return VLYNQ_SUCCESS;
1307 +}
1308 +
1309 +
1310 +/* ----------------------------------------------------------------------------
1311 + *  Function : vlynq_interrupt_vector_cntl()
1312 + *  Description:enables/disable interrupt
1313 + */
1314 +int vlynq_interrupt_vector_cntl( VLYNQ_DEV *pdev,
1315 +                                          unsigned int int_vector,
1316 +                                          VLYNQ_DEV_TYPE dev_type,
1317 +                                          unsigned int enable)
1318 +{
1319 +    volatile unsigned int *vecReg;
1320 +    unsigned int val=0;
1321 +    unsigned int intenMask=0x80;
1322 +
1323 +    /* validate the number of interrupts supported */
1324 +    if (int_vector >= VLYNQ_IVR_MAXIVR) 
1325 +        return VLYNQ_INVALID_ARG;
1326 +
1327 +    if (dev_type == VLYNQ_LOCAL_DVC)
1328 +    {
1329 +        vecReg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector));
1330 +    }
1331 +    else
1332 +    {
1333 +        vecReg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));  
1334 +    }
1335 +
1336 +    /** Clear the correct byte position and then or val **/
1337 +    *vecReg = (*vecReg) & ( ~(intenMask << ( (int_vector %4)*8) ) );
1338 +
1339 +    if(enable)
1340 +    {
1341 +        val |= VLYNQ_IVR_INTEN_MASK; 
1342 +        /** Write to correct byte position in vecReg*/
1343 +        *vecReg = (*vecReg) | (val << ( (int_vector % 4)*8) ) ;
1344 +    }
1345 +
1346 +    return VLYNQ_SUCCESS;
1347 +
1348 +}/* end of function vlynq_interrupt_vector_cntl */
1349 +
1350 +
1351 +
1352 +/* ----------------------------------------------------------------------------
1353 + *  Function : vlynq_interrupt_vector_map()
1354 + *  Description:Configures interrupt vector mapping alone
1355 + */
1356 +int 
1357 +vlynq_interrupt_vector_map( VLYNQ_DEV *pdev,
1358 +                            VLYNQ_DEV_TYPE dev_type,
1359 +                            unsigned int int_vector,
1360 +                            unsigned int map_vector)
1361 +{
1362 +    volatile unsigned int * vecreg;
1363 +    unsigned int val=0;
1364 +    unsigned int bytemask=0x1f;   /* mask to turn off bits corresponding to int vector */ 
1365 +
1366 +    /* use the lower 8 bits of val to set the value , shift it to 
1367 +     * appropriate byte position in the ivr and write it to the 
1368 +     * corresponding register */
1369 +
1370 +    /* validate the number of interrupts supported */
1371 +    if (int_vector >= VLYNQ_IVR_MAXIVR) 
1372 +        return VLYNQ_INVALID_ARG;
1373 +        
1374 +    if(map_vector > (VLYNQ_NUM_INT_BITS - 1) ) 
1375 +        return VLYNQ_INVALID_ARG;
1376 +
1377 +    if (dev_type == VLYNQ_LOCAL_DVC)
1378 +    {
1379 +        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector));
1380 +    }
1381 +    else
1382 +    {
1383 +        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));  
1384 +    }
1385 +
1386 +    /* Update the intVector<==> bit position translation table */
1387 +    pdev->vector_map[map_vector] = int_vector;
1388 +
1389 +    /** val has been initialised to zero. we only have to turn on
1390 +     * appropriate bits*/
1391 +    val |= map_vector;
1392 +
1393 +    /** clear the correct byte position and then or val **/
1394 +    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) );
1395 +
1396 +    /** write to correct byte position in vecreg*/
1397 +    *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ;
1398 +
1399 +    return VLYNQ_SUCCESS;
1400 +}
1401 +
1402 +
1403 +/* ----------------------------------------------------------------------------
1404 + *  function : vlynq_interrupt_set_polarity()
1405 + *  description:configures interrupt polarity .
1406 + */
1407 +int 
1408 +vlynq_interrupt_set_polarity( VLYNQ_DEV *pdev ,
1409 +                              VLYNQ_DEV_TYPE dev_type,
1410 +                              unsigned int map_vector,
1411 +                              VLYNQ_INTR_POLARITY pol)
1412 +{
1413 +    volatile unsigned int * vecreg;
1414 +    int int_vector;
1415 +    unsigned int val=0;
1416 +    unsigned int bytemask=0x20; /** mask to turn off bits corresponding to int polarity */
1417 +
1418 +    /* get the int_vector from map_vector */
1419 +    int_vector = pdev->vector_map[map_vector];
1420 +
1421 +    if(int_vector == -1) 
1422 +        return VLYNQ_INTVEC_MAP_NOT_FOUND;
1423 +
1424 +    /* use the lower 8 bits of val to set the value , shift it to 
1425 +     * appropriate byte position in the ivr and write it to the 
1426 +     * corresponding register */
1427 +
1428 +    if (dev_type == VLYNQ_LOCAL_DVC)
1429 +    {
1430 +        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector));
1431 +    }
1432 +    else
1433 +    {
1434 +        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));  
1435 +    }
1436 +
1437 +    /* val has been initialised to zero. we only have to turn on
1438 +     * appropriate bits, if need be*/
1439 +
1440 +    /** clear the correct byte position and then or val **/
1441 +    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) );
1442 +
1443 +    if( pol == VLYNQ_INTR_ACTIVE_LOW)
1444 +    {
1445 +        val |= VLYNQ_IVR_INTPOL_MASK;
1446 +        /** write to correct byte position in vecreg*/
1447 +        *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ;
1448 +    }
1449 +
1450 +    return VLYNQ_SUCCESS;
1451 +}
1452 +
1453 +int vlynq_interrupt_get_polarity( VLYNQ_DEV *pdev ,
1454 +                                           VLYNQ_DEV_TYPE dev_type,
1455 +                                           unsigned int map_vector)
1456 +{
1457 +    volatile unsigned int * vecreg;
1458 +    int int_vector;
1459 +    unsigned int val=0;
1460 +
1461 +    /* get the int_vector from map_vector */
1462 +    int_vector = pdev->vector_map[map_vector];
1463 +
1464 +    if (map_vector > (VLYNQ_NUM_INT_BITS-1))
1465 +        return(-1);
1466 +
1467 +    if(int_vector == -1) 
1468 +        return VLYNQ_INTVEC_MAP_NOT_FOUND;
1469 +
1470 +    /* use the lower 8 bits of val to set the value , shift it to 
1471 +     * appropriate byte position in the ivr and write it to the 
1472 +     * corresponding register */
1473 +
1474 +    if (dev_type == VLYNQ_LOCAL_DVC)
1475 +    {
1476 +        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector));
1477 +    }
1478 +    else
1479 +    {
1480 +        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));  
1481 +    }
1482 +
1483 +    /** read the information into val **/
1484 +    val = (*vecreg) & ((VLYNQ_IVR_INTPOL_MASK << ( (int_vector %4)*8) ) );
1485 +    
1486 +    return (val ? (VLYNQ_INTR_ACTIVE_LOW) : (VLYNQ_INTR_ACTIVE_HIGH));
1487 +}
1488 +
1489 +
1490 +/* ----------------------------------------------------------------------------
1491 + *  function : vlynq_interrupt_set_type()
1492 + *  description:configures interrupt type .
1493 + */
1494 +int vlynq_interrupt_set_type( VLYNQ_DEV *pdev,
1495 +                                       VLYNQ_DEV_TYPE dev_type,
1496 +                                       unsigned int map_vector,
1497 +                                       VLYNQ_INTR_TYPE type)
1498 +{
1499 +    volatile unsigned int * vecreg;
1500 +    unsigned int val=0;
1501 +    int int_vector;
1502 +
1503 +    /** mask to turn off bits corresponding to interrupt type */
1504 +    unsigned int bytemask=0x40;
1505 +
1506 +    /* get the int_vector from map_vector */
1507 +    int_vector = pdev->vector_map[map_vector];
1508 +    if(int_vector == -1) 
1509 +        return VLYNQ_INTVEC_MAP_NOT_FOUND;
1510 +
1511 +    /* use the lower 8 bits of val to set the value , shift it to 
1512 +     * appropriate byte position in the ivr and write it to the 
1513 +     * corresponding register */
1514 +    if (dev_type == VLYNQ_LOCAL_DVC)
1515 +    {
1516 +        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector));
1517 +    }
1518 +    else
1519 +    {
1520 +        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));  
1521 +    }
1522 +
1523 +    /** val has been initialised to zero. we only have to turn on
1524 +     * appropriate bits if need be*/
1525 +
1526 +     /** clear the correct byte position and then or val **/
1527 +    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) );
1528 +
1529 +    if( type == VLYNQ_INTR_PULSED)
1530 +    {
1531 +        val |= VLYNQ_IVR_INTTYPE_MASK;
1532 +        /** write to correct byte position in vecreg*/
1533 +        *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ;
1534 +    }
1535 +
1536 +    return VLYNQ_SUCCESS;
1537 +}
1538 +
1539 +/* ----------------------------------------------------------------------------
1540 + *  function : vlynq_interrupt_get_type()
1541 + *  description:returns interrupt type .
1542 + */
1543 +int vlynq_interrupt_get_type( VLYNQ_DEV *pdev, VLYNQ_DEV_TYPE dev_type,
1544 +                                       unsigned int map_vector)
1545 +{
1546 +    volatile unsigned int * vecreg;
1547 +    unsigned int val=0;
1548 +    int int_vector;
1549 +
1550 +    if (map_vector > (VLYNQ_NUM_INT_BITS-1))
1551 +        return(-1);
1552 +
1553 +    /* get the int_vector from map_vector */
1554 +    int_vector = pdev->vector_map[map_vector];
1555 +    if(int_vector == -1) 
1556 +        return VLYNQ_INTVEC_MAP_NOT_FOUND;
1557 +
1558 +    /* use the lower 8 bits of val to set the value , shift it to 
1559 +     * appropriate byte position in the ivr and write it to the 
1560 +     * corresponding register */
1561 +    if (dev_type == VLYNQ_LOCAL_DVC)
1562 +    {
1563 +        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector));
1564 +    }
1565 +    else
1566 +    {
1567 +        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));  
1568 +    }
1569 +
1570 +    /** Read the correct bit position into val **/
1571 +    val = (*vecreg) & ((VLYNQ_IVR_INTTYPE_MASK << ( (int_vector %4)*8) ) );
1572 +
1573 +    return (val ? (VLYNQ_INTR_PULSED) : (VLYNQ_INTR_LEVEL));
1574 +}
1575 +
1576 +/* ----------------------------------------------------------------------------
1577 + *  function : vlynq_interrupt_enable()
1578 + *  description:Enable interrupt by writing to IVR register.
1579 + */
1580 +int vlynq_interrupt_enable( VLYNQ_DEV *pdev,
1581 +                                     VLYNQ_DEV_TYPE dev_type,
1582 +                                     unsigned int map_vector)
1583 +{
1584 +    volatile unsigned int * vecreg;
1585 +    unsigned int val=0;
1586 +    int int_vector;
1587 +
1588 +    /** mask to turn off bits corresponding to interrupt enable */
1589 +    unsigned int bytemask=0x80;
1590 +
1591 +    /* get the int_vector from map_vector */
1592 +    int_vector = pdev->vector_map[map_vector];
1593 +    if(int_vector == -1) 
1594 +        return VLYNQ_INTVEC_MAP_NOT_FOUND;
1595 +
1596 +    /* use the lower 8 bits of val to set the value , shift it to 
1597 +     * appropriate byte position in the ivr and write it to the 
1598 +     * corresponding register */
1599 +
1600 +    if (dev_type == VLYNQ_LOCAL_DVC)
1601 +    {
1602 +        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector));
1603 +    }
1604 +    else
1605 +    {
1606 +        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));  
1607 +    }
1608 +
1609 +    /** val has been initialised to zero. we only have to turn on
1610 +    *  bit corresponding to interrupt enable*/
1611 +    val |= VLYNQ_IVR_INTEN_MASK;
1612 +
1613 +    /** clear the correct byte position and then or val **/
1614 +    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) );
1615 +
1616 +    /** write to correct byte position in vecreg*/
1617 +    *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ;
1618 +
1619 +    return VLYNQ_SUCCESS;
1620 +}
1621 +
1622 +
1623 +/* ----------------------------------------------------------------------------
1624 + *  function : vlynq_interrupt_disable()
1625 + *  description:Disable interrupt by writing to IVR register.
1626 + */
1627 +int 
1628 +vlynq_interrupt_disable( VLYNQ_DEV *pdev,
1629 +                         VLYNQ_DEV_TYPE dev_type,
1630 +                         unsigned int map_vector)
1631 +{
1632 +    volatile unsigned int * vecreg;
1633 +    int int_vector;
1634 +
1635 +    /** mask to turn off bits corresponding to interrupt enable */
1636 +    unsigned int bytemask=0x80;
1637 +
1638 +    /* get the int_vector from map_vector */
1639 +    int_vector = pdev->vector_map[map_vector];
1640 +    if(int_vector == -1) 
1641 +        return VLYNQ_INTVEC_MAP_NOT_FOUND;
1642 +
1643 +    /* use the lower 8 bits of val to set the value , shift it to 
1644 +     * appropriate byte position in the ivr and write it to the 
1645 +     * corresponding register */
1646 +    if (dev_type == VLYNQ_LOCAL_DVC)
1647 +    {
1648 +        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector));
1649 +    }
1650 +    else
1651 +    {
1652 +        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));  
1653 +    }
1654 +
1655 +    /* We disable the interrupt by simply turning off the bit
1656 +     * corresponding to Interrupt enable. 
1657 +     * Clear the interrupt enable bit in the correct byte position **/
1658 +    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) );
1659 +
1660 +    /* Dont have to set any bit positions */
1661 +
1662 +    return VLYNQ_SUCCESS;
1663 +
1664 +}
1665 +
1666 +
1667 +
1668 +
1669 diff -urN linux.old/drivers/char/Config.in linux.dev/drivers/char/Config.in
1670 --- linux.old/drivers/char/Config.in    2005-07-22 06:47:42.777975272 +0200
1671 +++ linux.dev/drivers/char/Config.in    2005-07-22 06:48:54.359093288 +0200
1672 @@ -192,6 +192,13 @@
1673     tristate 'Total Impact briQ front panel driver' CONFIG_BRIQ_PANEL
1674  fi
1675  
1676 +if [ "$CONFIG_AR7" = "y" ]; then  
1677 +   bool 'VLYNQ support for the TI SOC' CONFIG_AR7_VLYNQ
1678 +   dep_bool 'VLYNQ clock source Internal' CONFIG_VLYNQ_CLK_LOCAL $CONFIG_AR7_VLYNQ
1679 +                   
1680 +   define_int CONFIG_AR7_VLYNQ_PORTS 2 
1681 +fi                                                                                             
1682 +
1683  source drivers/i2c/Config.in
1684  
1685  mainmenu_option next_comment
1686 diff -urN linux.old/drivers/char/Makefile linux.dev/drivers/char/Makefile
1687 --- linux.old/drivers/char/Makefile     2005-07-22 06:47:35.151134728 +0200
1688 +++ linux.dev/drivers/char/Makefile     2005-07-22 06:32:53.360187328 +0200
1689 @@ -191,6 +191,13 @@
1690  endif
1691  
1692  #
1693 +# Texas Intruments VLYNQ driver
1694 +# 
1695 +
1696 +subdir-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq
1697 +obj-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq/avalanche_vlynq.o                                                        
1698 +
1699 +#
1700  # Texas Intruments LED driver
1701  # 
1702  obj-$(CONFIG_AR7_LED) += avalanche_led/avalanche_led.o
1703 diff -urN linux.old/include/asm-mips/ar7/vlynq.h linux.dev/include/asm-mips/ar7/vlynq.h
1704 --- linux.old/include/asm-mips/ar7/vlynq.h      1970-01-01 01:00:00.000000000 +0100
1705 +++ linux.dev/include/asm-mips/ar7/vlynq.h      2005-07-22 06:32:53.361187176 +0200
1706 @@ -0,0 +1,610 @@
1707 +/***************************************************************************
1708 +**+----------------------------------------------------------------------+**
1709 +**|                                ****                                  |**
1710 +**|                                ****                                  |**
1711 +**|                                ******o***                            |**
1712 +**|                          ********_///_****                           |**
1713 +**|                           ***** /_//_/ ****                          |**
1714 +**|                            ** ** (__/ ****                           |**
1715 +**|                                *********                             |**
1716 +**|                                 ****                                 |**
1717 +**|                                  ***                                 |**
1718 +**|                                                                      |**
1719 +**|     Copyright (c) 2003 Texas Instruments Incorporated                |**
1720 +**|                        ALL RIGHTS RESERVED                           |**
1721 +**|                                                                      |**
1722 +**| Permission is hereby granted to licensees of Texas Instruments       |**
1723 +**| Incorporated (TI) products to use this computer program for the sole |**
1724 +**| purpose of implementing a licensee product based on TI products.     |**
1725 +**| No other rights to reproduce, use, or disseminate this computer      |**
1726 +**| program, whether in part or in whole, are granted.                   |**
1727 +**|                                                                      |**
1728 +**| TI makes no representation or warranties with respect to the         |**
1729 +**| performance of this computer program, and specifically disclaims     |**
1730 +**| any responsibility for any damages, special or consequential,        |**
1731 +**| connected with the use of this program.                              |**
1732 +**|                                                                      |**
1733 +**+----------------------------------------------------------------------+**
1734 +***************************************************************************/
1735 +
1736 +/*********************************************************************************
1737 + *  ------------------------------------------------------------------------------
1738 + *   Module      : vlynq_hal.h
1739 + *   Description :
1740 + *   This header file provides the set of functions exported by the 
1741 + *   VLYNQ HAL. This file is included from the SOC specific VLYNQ driver wrapper.
1742 + *  ------------------------------------------------------------------------------
1743 + *********************************************************************************/
1744 +
1745 +#ifndef _VLYNQ_HAL_H_
1746 +#define _VLYNQ_HAL_H_
1747 +
1748 +/* Enable/Disable debug feature */
1749 +#undef VLYNQ_DEBUG 
1750 +
1751 +#ifdef VLYNQ_DEBUG  /* This needs to be OS abstracted - for testing use vxworks/linux calls */
1752 +#define debugPrint(format,args...)    
1753 +#else 
1754 +#define debugPrint(format,args...)  
1755 +#endif
1756 +
1757 + /* number of VLYNQ memory regions supported */
1758 +#define VLYNQ_MAX_MEMORY_REGIONS 0x04
1759 +  
1760 + /* Max.number of external interrupt inputs supported by VLYNQ module */
1761 +#define VLYNQ_IVR_MAXIVR         0x08
1762 +
1763 +#define VLYNQ_CLK_DIV_MAX  0x08
1764 +#define VLYNQ_CLK_DIV_MIN  0x01
1765 +
1766 +
1767 +/*** the total number of entries allocated for ICB would be
1768 + * 32(for 32 bits in IntPending register) + VLYNQ_IVR_CHAIN_SLOTS*/
1769 +#define VLYNQ_IVR_CHAIN_SLOTS 10
1770 +
1771 +
1772 +/* Error defines */
1773 +#define VLYNQ_SUCCESS               0
1774 +
1775 +#define VLYNQ_ERRCODE_BASE          0 /* Chosen by system */
1776 +#define VLYNQ_INVALID_ARG          -(VLYNQ_ERRCODE_BASE+1)
1777 +#define VLYNQ_INVALID_DRV_STATE    -(VLYNQ_ERRCODE_BASE+2)
1778 +#define VLYNQ_INT_CONFIG_ERR       -(VLYNQ_ERRCODE_BASE+3)
1779 +#define VLYNQ_LINK_DOWN            -(VLYNQ_ERRCODE_BASE+4)
1780 +#define VLYNQ_MEMALLOC_FAIL        -(VLYNQ_ERRCODE_BASE+5)
1781 +#define VLYNQ_ISR_NON_EXISTENT     -(VLYNQ_ERRCODE_BASE+6)
1782 +#define VLYNQ_INTVEC_MAP_NOT_FOUND -(VLYNQ_ERRCODE_BASE+7)
1783 +
1784 +/* Vlynq Defines and Macros */
1785 +
1786 +#define VLYNQ_NUM_INT_BITS              32 /* 32 bit interrupt staus register */
1787 +
1788 +/* Base address of module */
1789 +#define VLYNQ_BASE                      (pdev->module_base)
1790 +
1791 +#define VLYNQ_REMOTE_REGS_OFFSET        0x0080
1792 +
1793 +#define VLYNQ_REV_OFFSET                0x0000
1794 +#define VLYNQ_CTRL_OFFSET               0x0004
1795 +#define VLYNQ_STATUS_OFFSET             0x0008
1796 +#define VLYNQ_INT_STAT_OFFSET           0x0010
1797 +#define VLYNQ_INT_PEND_OFFSET           0x0014
1798 +#define VLYNQ_INT_PTR_OFFSET            0x0018
1799 +#define VLYNQ_TXMAP_OFFSET              0x001c
1800 +
1801 +#define VLYNQ_RX0MAP_SIZE_REG_OFFSET    0x0020
1802 +#define VLYNQ_RX0MAP_OFFSET_REG_OFFSET  0x0024
1803 +
1804 +#define VLYNQ_CHIP_VER_OFFSET           0x0040
1805 +#define VLYNQ_IVR_REGS_OFFSET           0x0060
1806 +
1807 +#define VLYNQ_INT_PENDING_REG_PTR       0x14
1808 +#define VLYNQ_R_INT_PENDING_REG_PTR     VLYNQ_REMOTE_REGS_OFFSET + 0x14
1809 +
1810 +#define VLYNQ_REV_REG       *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_REV_OFFSET))
1811 +#define VLYNQ_CTRL_REG      *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_CTRL_OFFSET))
1812 +#define VLYNQ_STATUS_REG    *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_STATUS_OFFSET))
1813 +#define VLYNQ_INT_STAT_REG  *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_INT_STAT_OFFSET))
1814 +#define VLYNQ_INT_PEND_REG  *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_INT_PEND_OFFSET))
1815 +#define VLYNQ_INT_PTR_REG   *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_INT_PTR_OFFSET))
1816 +#define VLYNQ_TXMAP_REG     *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_TXMAP_OFFSET))
1817 +
1818 +/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/
1819 +#define VLYNQ_RXMAP_SIZE_REG(map) \
1820 +    *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_RX0MAP_SIZE_REG_OFFSET+( (map-1)<<3)))
1821 +    
1822 +/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/
1823 +#define VLYNQ_RXMAP_OFFSET_REG(map) \
1824 +    *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_RX0MAP_OFFSET_REG_OFFSET+( (map-1)<<3)))
1825 +
1826 +#define VLYNQ_CHIP_VER_REG  *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_CHIP_VER_OFFSET))
1827 +
1828 +/* 0 =< ivr <= 31; currently ivr < VLYNQ_IVR_MAXIVR=8) */
1829 +#define VLYNQ_IVR_OFFSET(ivr)  \
1830 +    (VLYNQ_BASE + VLYNQ_IVR_REGS_OFFSET +((((unsigned)(ivr)) & 31) & ~3) )
1831 +
1832 +#define VLYNQ_IVR_03TO00_REG  *((volatile unsigned int*) (VLYNQ_IVR_OFFSET(0)) )
1833 +#define VLYNQ_IVR_07TO04_REG  *((volatile unsigned int*) (VLYNQ_IVR_OFFSET(4)) )
1834 +/*** Can be extended for 11TO08...31TO28 when all 31 are supported**/
1835 +
1836 +#define VLYNQ_IVR_INTEN(ivr)    (((unsigned int)(0x80)) << ((((unsigned)(ivr)) % 4) * 8))
1837 +#define VLYNQ_IVR_INTTYPE(ivr)  (((unsigned int)(0x40)) << ((((unsigned)(ivr)) % 4) * 8))
1838 +#define VLYNQ_IVR_INTPOL(ivr)   (((unsigned int)(0x20)) << ((((unsigned)(ivr)) % 4) * 8))
1839 +#define VLYNQ_IVR_INTVEC(ivr)   (((unsigned int)(0x1F)) << ((((unsigned)(ivr)) % 4) * 8))
1840 +#define VLYNQ_IVR_INTALL(ivr)   (((unsigned int)(0xFF)) << ((((unsigned)(ivr)) % 4) * 8))
1841 +
1842 +
1843 +
1844 +/*********************************
1845 + * Remote VLYNQ register set     *
1846 + *********************************/
1847 +
1848 +#define VLYNQ_R_REV_OFFSET              0x0080
1849 +#define VLYNQ_R_CTRL_OFFSET             0x0084
1850 +#define VLYNQ_R_STATUS_OFFSET           0x0088
1851 +#define VLYNQ_R_INT_STAT_OFFSET         0x0090
1852 +#define VLYNQ_R_INT_PEND_OFFSET         0x0094
1853 +#define VLYNQ_R_INT_PTR_OFFSET          0x0098
1854 +#define VLYNQ_R_TXMAP_OFFSET            0x009c
1855 +
1856 +#define VLYNQ_R_RX0MAP_SIZE_REG_OFFSET  0x00A0
1857 +#define VLYNQ_R_RX0MAP_OFFSET_REG_OFFSET 0x00A4
1858 +
1859 +#define VLYNQ_R_CHIP_VER_OFFSET         0x00C0
1860 +#define VLYNQ_R_IVR_REGS_OFFSET         0x00E0
1861 +
1862 +#define VLYNQ_R_REV_REG       *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_REV_OFFSET)) 
1863 +#define VLYNQ_R_CTRL_REG      *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_CTRL_OFFSET))
1864 +#define VLYNQ_R_STATUS_REG    *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_STATUS_OFFSET))
1865 +#define VLYNQ_R_INT_STAT_REG  *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_INT_STAT_OFFSET))
1866 +#define VLYNQ_R_INT_PEND_REG  *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_INT_PEND_OFFSET))
1867 +#define VLYNQ_R_INT_PTR_REG   *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_INT_PTR_OFFSET))
1868 +#define VLYNQ_R_TXMAP_REG     *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_TXMAP_OFFSET))
1869 +
1870 +/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/
1871 +#define VLYNQ_R_RXMAP_SIZE_REG(map) \
1872 +    *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_RX0MAP_SIZE_REG_OFFSET + ((map-1)<<3)))
1873 +    
1874 +/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/
1875 +#define VLYNQ_R_RXMAP_OFFSET_REG(map) \
1876 +    *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_RX0MAP_OFFSET_REG_OFFSET + ((map-1)<<3)))
1877 +
1878 +#define VLYNQ_R_CHIP_VER_REG  *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_CHIP_VER_OFFSET)
1879 +
1880 +#define VLYNQ_R_IVR_OFFSET(ivr)  \
1881 +    (VLYNQ_BASE + VLYNQ_R_IVR_REGS_OFFSET +((((unsigned)(ivr)) & 31) & ~3))
1882
1883 +
1884 +/*** Can be extended for 11TO08...31TO28 when all 31 are supported**/
1885 +#define VLYNQ_R_IVR_03TO00_REG  *((volatile unsigned int*) (VLYNQ_R_IVR_OFFSET(0)) )
1886 +#define VLYNQ_R_IVR_07TO04_REG  *((volatile unsigned int*) (VLYNQ_R_IVR_OFFSET(4)) )
1887 +
1888 +
1889 +/****End of remote register set definition******/
1890 +
1891 +
1892 +/*** Masks for individual register fields ***/
1893 +
1894 +#define VLYNQ_MODULE_ID_MASK        0xffff0000
1895 +#define VLYNQ_MAJOR_REV_MASK        0x0000ff00
1896 +#define VLYNQ_MINOR_REV_MASK        0x000000ff
1897 +
1898 +    
1899 +#define VLYNQ_CTL_ILOOP_MASK        0x00000002
1900 +#define VLYNQ_CTL_INT2CFG_MASK      0x00000080
1901 +#define VLYNQ_CTL_INTVEC_MASK       0x00001f00
1902 +#define VLYNQ_CTL_INTEN_MASK        0x00002000
1903 +#define VLYNQ_CTL_INTLOCAL_MASK     0x00004000
1904 +#define VLYNQ_CTL_CLKDIR_MASK       0x00008000
1905 +#define VLYNQ_CTL_CLKDIV_MASK       0x00070000
1906 +#define VLYNQ_CTL_MODE_MASK         0x00e00000
1907 +
1908 +
1909 +#define VLYNQ_STS_LINK_MASK         0x00000001  /* Link is active */
1910 +#define VLYNQ_STS_MPEND_MASK        0x00000002  /* Pending master requests */
1911 +#define VLYNQ_STS_SPEND_MASK        0x00000004  /* Pending slave requests */
1912 +#define VLYNQ_STS_NFEMPTY0_MASK     0x00000008  /* Master data FIFO not empty */
1913 +#define VLYNQ_STS_NFEMPTY1_MASK     0x00000010  /* Master command FIFO not empty */
1914 +#define VLYNQ_STS_NFEMPTY2_MASK     0x00000020  /* Slave data FIFO not empty */
1915 +#define VLYNQ_STS_NFEMPTY3_MASK     0x00000040  /* Slave command FIFO not empty */
1916 +#define VLYNQ_STS_LERROR_MASK       0x00000080  /* Local error, w/c */
1917 +#define VLYNQ_STS_RERROR_MASK       0x00000100  /* remote error w/c */
1918 +#define VLYNQ_STS_OFLOW_MASK        0x00000200
1919 +#define VLYNQ_STS_IFLOW_MASK        0x00000400
1920 +#define VLYNQ_STS_MODESUP_MASK      0x00E00000  /* Highest mode supported */
1921 +#define VLYNQ_STS_SWIDTH_MASK       0x07000000  /* Used for reading the width of VLYNQ bus */
1922 +#define VLYNQ_STS_DEBUG_MASK        0xE0000000 
1923 +
1924 +#define VLYNQ_CTL_INTVEC_SHIFT      0x08
1925 +#define VLYNQ_CTL_INTEN_SHIFT       0x0D
1926 +#define VLYNQ_CTL_INT2CFG_SHIFT     0x07
1927 +#define VLYNQ_CTL_INTLOCAL_SHIFT    0x0E
1928 +
1929 +#define VLYNQ_CTL_INTFIELDS_CLEAR_MASK  0x7F80
1930 +
1931 +#define VLYNQ_CHIPVER_DEVREV_MASK   0xffff0000
1932 +#define VLYNQ_CHIPVER_DEVID_MASK    0x0000ffff
1933 +
1934 +#define VLYNQ_IVR_INTEN_MASK        0x80
1935 +#define VLYNQ_IVR_INTTYPE_MASK      0x40
1936 +#define VLYNQ_IVR_INTPOL_MASK       0x20
1937 +
1938 +
1939 +/**** Helper macros ****/
1940 +
1941 +#define VLYNQ_RESETCB(arg) \
1942 +   if( pdev->reset_cb != NULL)   \
1943 +   {                             \
1944 +      (pdev->reset_cb)(pdev, (arg));  \
1945 +   }
1946 +    
1947 +#define VLYNQ_STATUS_FLD_WIDTH(sts) (((sts) & VLYNQ_STS_SWIDTH_MASK) >> 24 )
1948 +#define VLYNQ_CTL_INTVEC(x)         (((x) & 31) << 8 )
1949 +
1950 +#define VLYNQ_INRANGE(x,hi,lo)      (((x) <= (hi)) && ((x) >= (lo)))
1951 +#define VLYNQ_OUTRANGE(x,hi,lo)     (((x) > (hi)) || ((x) < (lo)))
1952 +
1953 +#define VLYNQ_ALIGN4(x)             (x)=(x)&(~3)   
1954 +
1955 +
1956 +/*************************************
1957 + *             Enums                 *
1958 + *************************************/
1959 +
1960 +/* Initialization options define what operations are
1961 + * undertaken during vlynq module initialization */
1962 +typedef enum
1963 +{
1964 +    /* Init host local memory regions.This allows
1965 +     * local host access remote memory regions */
1966 +    VLYNQ_INIT_LOCAL_MEM_REGIONS = 0x01,
1967 +    /* Init host remote memory regions.This allows
1968 +     * remote device access local memory regions */
1969 +    VLYNQ_INIT_REMOTE_MEM_REGIONS =0x02,
1970 +    /* Init local interrupt config*/
1971 +    VLYNQ_INIT_LOCAL_INTERRUPTS   =0x04,
1972 +    /* Init remote interrupt config*/
1973 +    VLYNQ_INIT_REMOTE_INTERRUPTS  =0x08,
1974 +    /* Check link during initialization*/
1975 +    VLYNQ_INIT_CHECK_LINK         =0x10,
1976 +    /* configure clock during init */
1977 +    VLYNQ_INIT_CONFIG_CLOCK       =0x20,
1978 +    /* Clear errors during init */    
1979 +    VLYNQ_INIT_CLEAR_ERRORS       =0x40,
1980 +    /* All options */
1981 +    VLYNQ_INIT_PERFORM_ALL        =0x7F
1982 +}VLYNQ_INIT_OPTIONS;
1983 +
1984 +
1985 +/* VLYNQ_DEV_TYPE identifies local or remote device */
1986 +typedef enum
1987 +{
1988 +    VLYNQ_LOCAL_DVC  = 0,           /* vlynq local device (SOC's vlynq module) */
1989 +    VLYNQ_REMOTE_DVC = 1            /* vlynq remote device (remote vlynq module) */
1990 +}VLYNQ_DEV_TYPE;
1991 +
1992 +
1993 +/* VLYNQ_CLK_SOURCE identifies the vlynq module clock source */
1994 +typedef enum
1995 +{
1996 +    VLYNQ_CLK_SOURCE_NONE   = 0,    /* do not initialize clock generator*/
1997 +    VLYNQ_CLK_SOURCE_LOCAL  = 1,    /* clock is generated by local machine  */
1998 +    VLYNQ_CLK_SOURCE_REMOTE = 2     /* clock is generated by remote machine */
1999 +}VLYNQ_CLK_SOURCE;
2000 +
2001 +
2002 +/* VLYNQ_DRV_STATE indicates the current driver state */
2003 +typedef enum
2004 +{
2005 +    VLYNQ_DRV_STATE_UNINIT = 0,     /* driver is uninitialized  */
2006 +    VLYNQ_DRV_STATE_ININIT = 1,     /* VLYNQ is being initialized */
2007 +    VLYNQ_DRV_STATE_RUN    = 2,     /* VLYNQ is running properly  */
2008 +    VLYNQ_DRV_STATE_HOLD   = 3,     /* driver stopped temporarily */
2009 +    VLYNQ_DRV_STATE_ERROR  = 4      /* driver stopped on unrecoverable error */
2010 +}VLYNQ_DRV_STATE;
2011 +
2012 +
2013 +/* VLYNQ_BUS_WIDTH identifies the vlynq module bus width */
2014 +typedef enum
2015 +{
2016 +   VLYNQ_BUS_WIDTH_3 =  3,
2017 +   VLYNQ_BUS_WIDTH_5 =  5,
2018 +   VLYNQ_BUS_WIDTH_7 =  7,
2019 +   VLYNQ_BUS_WIDTH_9 =  9
2020 +}VLYNQ_BUS_WIDTH;
2021 +
2022 +
2023 +/* VLYNQ_LOCAL_INT_CONFIG indicates whether the local vlynq 
2024 + * interrupts are processed by the host or passed on to the 
2025 + * remote device.
2026 + */
2027 +typedef enum
2028 +{
2029 +    VLYNQ_INT_REMOTE = 0,   /* Interrupt packets sent to remote, intlocal=0 */
2030 +    VLYNQ_INT_LOCAL  = 1    /* Interrupts are handled locally, intlocal=1 */
2031 +}VLYNQ_LOCAL_INT_CONFIG;        
2032 +
2033 +
2034 +/* VLYNQ_REMOTE_INT_CONFIG indicates whether the remote 
2035 + * interrupts are to be handled by the SOC system ISR 
2036 + * or via the vlynq root ISR
2037 + */
2038 +typedef enum 
2039 +{
2040 +    VLYNQ_INT_ROOT_ISR   = 0,   /* remote ints handled via vlynq root ISR */
2041 +    VLYNQ_INT_SYSTEM_ISR = 1    /* remote ints handled via system ISR */
2042 +}VLYNQ_REMOTE_INT_CONFIG;
2043 +
2044 +
2045 +/* VLYNQ_INTR_POLARITY - vlynq interrupt polarity setting */
2046 +typedef enum
2047 +{
2048 +    VLYNQ_INTR_ACTIVE_HIGH = 0,
2049 +    VLYNQ_INTR_ACTIVE_LOW  = 1
2050 +}VLYNQ_INTR_POLARITY;
2051 +
2052 +
2053 +/* VLYNQ_INTR_TYPE  - vlynq interrupt type */
2054 +typedef enum
2055 +{
2056 +    VLYNQ_INTR_LEVEL  = 0,
2057 +    VLYNQ_INTR_PULSED = 1
2058 +}VLYNQ_INTR_TYPE;
2059 +
2060 +
2061 +/* VLYNQ_RESET_MODE - vlynq reset mode */
2062 +typedef enum
2063 +{
2064 +   VLYNQ_RESET_ASSERT,      /* hold device in reset state */
2065 +   VLYNQ_RESET_DEASSERT,    /* release device from reset state */
2066 +   VLYNQ_RESET_INITFAIL,    /* handle the device in case driver initialization fails */
2067 +   VLYNQ_RESET_LINKESTABLISH,  /* handle the device in case driver established link */
2068 +   VLYNQ_RESET_INITFAIL2,   /* Driver initialization failed but VLYNQ link exist. */
2069 +   VLYNQ_RESET_INITOK       /* Driver initialization finished OK. */
2070 +}VLYNQ_RESET_MODE;
2071
2072 +
2073 +
2074 +/*************************************
2075 + *             Typedefs              *
2076 + *************************************/
2077 +
2078 +struct VLYNQ_DEV_t; /*forward declaration*/
2079 +
2080 +/*--------Function Pointers defintions -----------*/
2081 +
2082 +/* prototype for interrupt handler definition */
2083 +typedef void (*VLYNQ_INTR_CNTRL_ISR)(void *arg1,void *arg2,void *arg3);
2084 +
2085 +typedef void 
2086 +(*VLYNQ_RESET_REMOTE)(struct VLYNQ_DEV_t *pDev, VLYNQ_RESET_MODE mode);
2087 +
2088 +typedef void 
2089 +(*VLYNQ_REPORT_CB)( struct VLYNQ_DEV_t *pDev,   /* This VLYNQ */
2090 +                    VLYNQ_DEV_TYPE  aSrcDvc,    /* Event Cause -local/remote? */
2091 +                    unsigned int  dwStatRegVal);      /* Value of the relevant status register */
2092 +
2093 +
2094 +/*-------Structure Definitions------------*/
2095 +
2096 +typedef struct VLYNQ_MEMORY_MAP_t
2097 +{
2098 +    unsigned int Txmap;
2099 +    unsigned int RxOffset[VLYNQ_MAX_MEMORY_REGIONS];
2100 +    unsigned int RxSize[VLYNQ_MAX_MEMORY_REGIONS];
2101 +}VLYNQ_MEMORY_MAP;
2102 +
2103 +
2104 +/**VLYNQ_INTERRUPT_CNTRL - defines the vlynq module interrupt
2105 + * settings in vlynq Control register  */ 
2106 +typedef struct VLYNQ_INTERRUPT_CNTRL_t
2107 +{
2108 +    /* vlynq interrupts handled by host or remote - maps to 
2109 +     * intLocal bit in vlynq control register */
2110 +    VLYNQ_LOCAL_INT_CONFIG intLocal;
2111 +
2112 +    /* remote interrupts handled by vlynq isr or host system
2113 +     * interrupt controller - maps to the int2Cfg in vlynq 
2114 +     * control register */
2115 +    VLYNQ_REMOTE_INT_CONFIG intRemote;
2116 +    
2117 +    /* bit in pending/set register used for module interrupts*/
2118 +    unsigned int map_vector;
2119 +    
2120 +    /* used only if remote interrupts are to be handled by system ISR*/    
2121 +    unsigned int intr_ptr;
2122 +
2123 +}VLYNQ_INTERRUPT_CNTRL;
2124 +
2125 +
2126 +/* VLYNQ_INTR_CNTRL_ICB - defines the Interrupt control block which hold
2127 + * the interrupt dispatch table. The vlynq_root_isr() indexes into this 
2128 + * table to identify the ISR to be invoked
2129 + */
2130 +typedef struct VLYNQ_INTR_CNTRL_ICB_t
2131 +{
2132 +    VLYNQ_INTR_CNTRL_ISR            isr;    /* Clear errors during initialization */
2133 +    void                            *arg1 ; /* Arg 1 for the ISR */
2134 +    void                            *arg2 ; /* Arg 2 for the ISR */
2135 +    void                            *arg3 ; /* Arg 3 for the ISR */
2136 +    unsigned int  isrCount; /* number of ISR invocations so far */
2137 +    struct VLYNQ_INTR_CNTRL_ICB_t   *next;
2138 +}VLYNQ_INTR_CNTRL_ICB;
2139 +
2140 +/* overlay of vlynq register set */
2141 +typedef struct VLYNQ_REG_SET_t
2142 +{
2143 +    unsigned int revision; /*offset : 0x00 */
2144 +    unsigned int control;  /* 0x04*/
2145 +    unsigned int status;   /* 0x08*/
2146 +    unsigned int pad1;     /* 0x0c*/
2147 +    unsigned int intStatus;   /*0x10*/
2148 +    unsigned int intPending;  /*0x14*/
2149 +    unsigned int intPtr;      /*0x18*/
2150 +    unsigned int txMap;       /*0x1C*/ 
2151 +    unsigned int rxSize1;     /*0x20*/
2152 +    unsigned int rxOffset1;   /*0x24*/
2153 +    unsigned int rxSize2;     /*0x28*/
2154 +    unsigned int rxOffset2;   /*0x2C*/
2155 +    unsigned int rxSize3;     /*0x30*/
2156 +    unsigned int rxOffset3;   /*0x34*/
2157 +    unsigned int rxSize4;     /*0x38*/
2158 +    unsigned int rxOffset4;   /*0x3C*/
2159 +    unsigned int chipVersion; /*0x40*/
2160 +    unsigned int pad2[8];
2161 +    unsigned int ivr30;       /*0x60*/
2162 +    unsigned int ivr74;       /*0x64*/
2163 +    unsigned int pad3[7];
2164 +}VLYNQ_REG_SET;
2165 +    
2166 +
2167 +typedef struct VLYNQ_DEV_t
2168 +{
2169 +    /** module index:1,2,3... used for debugging purposes */
2170 +    unsigned int dev_idx; 
2171 +    
2172 +    /*VLYNQ module base address */
2173 +    unsigned int module_base;
2174 +   
2175 +    /* clock source selection */
2176 +    VLYNQ_CLK_SOURCE clk_source;
2177 +   
2178 +    /* Clock Divider.Val=1 to 8. VLYNQ_clk = VBUSCLK/clk_div */
2179 +    unsigned int  clk_div;
2180 +   
2181 +    /* State of the VLYNQ driver, set to VLYNQ_DRV_STATE_UNINIT, when initializing */
2182 +    VLYNQ_DRV_STATE state;
2183 +   
2184 +    /* Valid VLYNQ bus width, filled by driver  */
2185 +    VLYNQ_BUS_WIDTH width;
2186 +   
2187 +    /* local memory mapping   */
2188 +    VLYNQ_MEMORY_MAP local_mem;
2189 +   
2190 +    /* remote memory mapping   */
2191 +    VLYNQ_MEMORY_MAP remote_mem;
2192 +   
2193 +    /* Local module interrupt params */
2194 +    VLYNQ_INTERRUPT_CNTRL  local_irq;
2195 +   
2196 +    /* remote module interrupt params */
2197 +    VLYNQ_INTERRUPT_CNTRL  remote_irq;
2198 +
2199 +    /*** ICB related fields **/
2200 +   
2201 +    /* Sizeof of ICB = VLYNQ_NUM_INT_BITS(for 32 bits in IntPending) + 
2202 +     * expansion slots for shared interrupts*/
2203 +    VLYNQ_INTR_CNTRL_ICB  pIntrCB[VLYNQ_NUM_INT_BITS + VLYNQ_IVR_CHAIN_SLOTS];
2204 +    VLYNQ_INTR_CNTRL_ICB  *freelist;
2205 +   
2206 +   /* table holding mapping between intVector and the bit position the interrupt
2207 +    * is mapped to(mapVector)*/
2208 +    char vector_map[32];
2209 +   
2210 +    /* user callback for vlynq events, NULL if unused */
2211 +    VLYNQ_REPORT_CB        report_cb;    
2212 +    
2213 +   /* user callback for resetting/realeasing remote device */
2214 +    VLYNQ_RESET_REMOTE     reset_cb;
2215 +
2216 +    /*** Handles provided for direct access to register set if need be
2217 +     * Must be intialized to point to appropriate address during 
2218 +     * vlynq_init */
2219 +    volatile VLYNQ_REG_SET * local;
2220 +    volatile VLYNQ_REG_SET * remote;
2221 +
2222 +    unsigned int  intCount; /* number of interrupts generated so far */
2223 +    unsigned int  isrCount; /* number of ISR invocations so far */
2224 +}VLYNQ_DEV;
2225 +
2226 +
2227 +typedef struct VLYNQ_ISR_ARGS_t
2228 +{
2229 +    int irq;
2230 +    void * arg;
2231 +    void * regset;
2232 +}VLYNQ_ISR_ARGS;
2233 +
2234 +
2235 +/****************************************
2236 + *        Function Prototypes           *
2237 + * API exported by generic vlynq driver *
2238 + ****************************************/
2239 +/* Initialization function */ 
2240 +int vlynq_init( VLYNQ_DEV *pdev, VLYNQ_INIT_OPTIONS options);
2241 +
2242 +/* Check vlynq link */
2243 +unsigned int vlynq_link_check( VLYNQ_DEV * pdev);
2244 +
2245 +/* Set interrupt vector in local or remote device */
2246 +int vlynq_interrupt_vector_set( VLYNQ_DEV *pdev, 
2247 +                                         unsigned int int_vector,
2248 +                                         unsigned int map_vector, 
2249 +                                         VLYNQ_DEV_TYPE dev,
2250 +                                         VLYNQ_INTR_POLARITY pol,
2251 +                                         VLYNQ_INTR_TYPE type);
2252 +
2253 +
2254 +int vlynq_interrupt_vector_cntl( VLYNQ_DEV *pdev,
2255 +                                          unsigned int int_vector,
2256 +                                          VLYNQ_DEV_TYPE dev,
2257 +                                          unsigned int enable);
2258 +
2259 +unsigned int vlynq_interrupt_get_count( VLYNQ_DEV *pdev,
2260 +                                         unsigned int map_vector);
2261 +
2262 +int vlynq_install_isr( VLYNQ_DEV *pdev,
2263 +                                unsigned int map_vector,
2264 +                                VLYNQ_INTR_CNTRL_ISR isr,
2265 +                                void *arg1, void *arg2, void *arg3);
2266 +
2267 +int vlynq_uninstall_isr( VLYNQ_DEV *pdev,
2268 +                                  unsigned int map_vector,
2269 +                                  void *arg1, void *arg2, void *arg3);
2270 +
2271 +
2272 +void vlynq_root_isr(void *arg);
2273 +
2274 +void vlynq_delay(unsigned int clktime);
2275 +
2276 +/* The following functions, provide better granularity in setting
2277 + * interrupt parameters. (for better support of linux INT Controller)
2278 + * Note: The interrupt source is identified by "map_vector"- the bit 
2279 + * position in interrupt status register*/
2280 +
2281 +int vlynq_interrupt_vector_map(VLYNQ_DEV * pdev,
2282 +                                        VLYNQ_DEV_TYPE dev,
2283 +                                        unsigned int int_vector,
2284 +                                        unsigned int map_vector);
2285 +
2286 +int vlynq_interrupt_set_polarity(VLYNQ_DEV * pdev,
2287 +                                          VLYNQ_DEV_TYPE dev,
2288 +                                          unsigned int map_vector,
2289 +                                          VLYNQ_INTR_POLARITY pol);
2290 +
2291 +int vlynq_interrupt_get_polarity( VLYNQ_DEV *pdev ,
2292 +                                           VLYNQ_DEV_TYPE dev_type,
2293 +                                           unsigned int map_vector);
2294 +
2295 +int vlynq_interrupt_set_type(VLYNQ_DEV * pdev,
2296 +                                      VLYNQ_DEV_TYPE dev,
2297 +                                      unsigned int map_vector,
2298 +                                      VLYNQ_INTR_TYPE type);
2299 +
2300 +int vlynq_interrupt_get_type( VLYNQ_DEV *pdev, 
2301 +                                       VLYNQ_DEV_TYPE dev_type,
2302 +                                       unsigned int map_vector);
2303 +
2304 +int vlynq_interrupt_enable(VLYNQ_DEV* pdev,
2305 +                                    VLYNQ_DEV_TYPE dev,
2306 +                                    unsigned int map_vector);
2307 +
2308 +int vlynq_interrupt_disable(VLYNQ_DEV * pdev,
2309 +                                     VLYNQ_DEV_TYPE dev,
2310 +                                     unsigned int map_vector);
2311 +                 
2312 +
2313 +              
2314 +        
2315 +
2316 +#endif /* _VLYNQ_HAL_H_ */