Changeset 2363


Ignore:
Timestamp:
2005-11-07T02:10:50+01:00 (12 years ago)
Author:
nbd
Message:

add first batch of enrik's ar7 system code cleanups

Location:
trunk/openwrt/target/linux/linux-2.4
Files:
1 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/openwrt/target/linux/linux-2.4/config/ar7

    r1905 r2363  
    746746CONFIG_VLYNQ_CLK_LOCAL=y 
    747747CONFIG_AR7_VLYNQ_PORTS=2 
     748CONFIG_AR7_ADAM2=y 
    748749 
    749750# 
  • trunk/openwrt/target/linux/linux-2.4/patches/ar7/000-ar7_support.patch

    r1611 r2363  
     1diff -urN linux.old/Makefile linux.dev/Makefile 
     2--- linux.old/Makefile  2005-10-21 16:43:16.316951500 +0200 
     3+++ linux.dev/Makefile  2005-10-21 16:45:42.294074500 +0200 
     4@@ -91,7 +91,7 @@ 
     5  
     6 CPPFLAGS := -D__KERNEL__ -I$(HPATH) 
     7  
     8-CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ 
     9+CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ 
     10          -fno-strict-aliasing -fno-common 
     11 ifndef CONFIG_FRAME_POINTER 
     12 CFLAGS += -fomit-frame-pointer 
     13diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile 
     14--- linux.old/arch/mips/Makefile        2005-10-21 16:43:16.316951500 +0200 
     15+++ linux.dev/arch/mips/Makefile        2005-10-21 16:45:42.134064500 +0200 
     16@@ -369,6 +369,16 @@ 
     17 endif 
     18  
     19 # 
     20+# Texas Instruments AR7 
     21+# 
     22+ 
     23+ifdef CONFIG_AR7 
     24+LIBS           += arch/mips/ar7/ar7.o 
     25+SUBDIRS                += arch/mips/ar7 
     26+LOADADDR       += 0x94020000 
     27+endif 
     28+ 
     29+# 
     30 # DECstation family 
     31 # 
     32 ifdef CONFIG_DECSTATION 
     33diff -urN linux.old/arch/mips/ar7/Makefile linux.dev/arch/mips/ar7/Makefile 
     34--- linux.old/arch/mips/ar7/Makefile    1970-01-01 01:00:00.000000000 +0100 
     35+++ linux.dev/arch/mips/ar7/Makefile    2005-10-21 17:02:14.507635750 +0200 
     36@@ -0,0 +1,14 @@ 
     37+.S.s: 
     38+       $(CPP) $(AFLAGS) $< -o $*.s 
     39+ 
     40+.S.o: 
     41+       $(CC) $(AFLAGS) -c $< -o $*.o 
     42+ 
     43+EXTRA_CFLAGS := -I$(TOPDIR)/include/asm/ar7 -DLITTLE_ENDIAN -D_LINK_KSEG0_ 
     44+O_TARGET := ar7.o 
     45+ 
     46+obj-y := tnetd73xx_misc.o misc.o 
     47+export-objs := misc.o irq.o init.o 
     48+obj-y += setup.o irq.o mipsIRQ.o reset.o init.o psp_env.o memory.o printf.o cmdline.o time.o 
     49+ 
     50+include $(TOPDIR)/Rules.make 
    151diff -urN linux.old/arch/mips/ar7/cmdline.c linux.dev/arch/mips/ar7/cmdline.c 
    252--- linux.old/arch/mips/ar7/cmdline.c   1970-01-01 01:00:00.000000000 +0100 
    3 +++ linux.dev/arch/mips/ar7/cmdline.c   2005-08-12 19:32:05.137225512 +0200 
     53+++ linux.dev/arch/mips/ar7/cmdline.c   2005-10-21 16:45:42.090061750 +0200 
    454@@ -0,0 +1,64 @@ 
    555+/* 
     
    69119diff -urN linux.old/arch/mips/ar7/init.c linux.dev/arch/mips/ar7/init.c 
    70120--- linux.old/arch/mips/ar7/init.c      1970-01-01 01:00:00.000000000 +0100 
    71 +++ linux.dev/arch/mips/ar7/init.c      2005-08-12 19:34:07.215666768 +0200 
    72 @@ -0,0 +1,182 @@ 
     121+++ linux.dev/arch/mips/ar7/init.c      2005-10-21 17:02:14.507635750 +0200 
     122@@ -0,0 +1,199 @@ 
    73123+/* 
    74124+ * Carsten Langgaard, carstenl@mips.com 
     
    100150+#include <asm/mips-boards/generic.h> 
    101151+ 
    102 +/* Environment variable */ 
    103 +typedef struct { 
    104 +       char *name; 
    105 +       char *val; 
    106 +} t_env_var; 
     152+#include <asm/ar7/adam2_env.h> 
    107153+ 
    108154+int prom_argc; 
     
    145191+} 
    146192+ 
     193+/* XXX "bootloader" won't be returned. 
     194+ * Better make it an element of local_envp */ 
     195+static inline t_env_var * 
     196+prom_adam2_iterenv(t_env_var *env) { 
     197+       if (!env) 
     198+         env = local_envp; 
     199+       else 
     200+         env++; 
     201+       if (env - local_envp > MAX_ENV_ENTRY || !env->name) 
     202+         return 0; 
     203+       return env; 
     204+} 
     205+ 
    147206+char *prom_getenv(char *envname) 
    148207+{ 
     
    151210+       else 
    152211+               return prom_adam2_getenv(envname); 
     212+} 
     213+ 
     214+t_env_var * 
     215+prom_iterenv(t_env_var *last) 
     216+{ 
     217+       if (env_type == 1) 
     218+         return 0; /* not yet implemented */ 
     219+       return prom_adam2_iterenv(last); 
    153220+} 
    154221+ 
     
    255322diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c 
    256323--- linux.old/arch/mips/ar7/irq.c       1970-01-01 01:00:00.000000000 +0100 
    257 +++ linux.dev/arch/mips/ar7/irq.c       2005-08-12 23:42:18.679820112 +0200 
    258 @@ -0,0 +1,709 @@ 
     324+++ linux.dev/arch/mips/ar7/irq.c       2005-10-21 17:02:14.507635750 +0200 
     325@@ -0,0 +1,925 @@ 
    259326+/* 
    260327+ * Nitin Dhingra, iamnd@ti.com 
     
    290357+#include <linux/kernel_stat.h> 
    291358+#include <linux/proc_fs.h> 
     359+#include <linux/module.h> 
    292360+#include <asm/irq.h> 
    293361+#include <asm/mips-boards/prom.h> 
     
    329397+extern asmlinkage void mipsIRQ(void); 
    330398+ 
     399+#ifdef CONFIG_AR7_VLYNQ 
     400+#include <asm/ar7/vlynq.h> 
     401+extern VLYNQ_DEV vlynqDevice0, vlynqDevice1; 
     402+#endif 
    331403+ 
    332404+/* 
     
    407479+       if(irq_nr >= AVALANCHE_INT_END) 
    408480+       { 
    409 +               printk("whee, invalid irq_nr %d\n", irq_nr); 
     481+               printk(KERN_ERR "%s: whee, invalid irq_nr %d\n", 
     482+                      __FUNCTION__, irq_nr); 
    410483+               panic("IRQ, you lose..."); 
    411484+       } 
     
    424497+       } 
    425498+ 
     499+#if defined (CONFIG_AR7_VLYNQ) 
     500+        /* Vlynq irq_nr are 72-145 in the system and are placed after 
     501+        * the interrupts managed by the interrupt controller. 
     502+         */ 
     503+        if(irq_nr >= AVALANCHE_INTC_END) 
     504+        { 
     505+            if(irq_nr >= AVALANCHE_INT_END_LOW_VLYNQ) 
     506+                /* Vlynq interrupts 32-63 */ 
     507+                vlynq_interrupt_disable(&vlynqDevice1,VLYNQ_REMOTE_DVC, 
     508+                                       irq_nr-AVALANCHE_INT_END_LOW_VLYNQ); 
     509+            else 
     510+                /* Vlynq interupts 0-31 */ 
     511+                vlynq_interrupt_disable(&vlynqDevice0,VLYNQ_REMOTE_DVC, 
     512+                                       irq_nr-AVALANCHE_INTC_END); 
     513+ 
     514+            goto ret_from_disable_irq; 
     515+        } 
     516+#endif 
     517+ 
    426518+       /* irq_nr represents the line number for the interrupt.  We must 
    427519+        *  disable the channel number associated with that line number. 
     
    449541+               avalanche_hw0_ecregs->exiecr = (1 << (chan_nr - AVINTNUM(AVALANCHE_INT_END_PRIMARY))); 
    450542+ 
     543+#if defined (CONFIG_AR7_VLYNQ) 
     544+ret_from_disable_irq: 
     545+#endif 
     546+ 
    451547+       restore_flags(flags); 
    452548+} 
     
    459555+ 
    460556+       if(irq_nr > AVALANCHE_INT_END) { 
    461 +               printk("whee, invalid irq_nr %d\n", irq_nr); 
     557+               printk(KERN_ERR "%s: whee, invalid irq_nr %d\n", 
     558+                      __FUNCTION__, irq_nr); 
    462559+               panic("IRQ, you lose..."); 
    463560+       } 
     
    475572+       } 
    476573+ 
     574+#if defined (CONFIG_AR7_VLYNQ) 
     575+        /* Vlynq irq_nr are 80-143 in the system and are placed after 
     576+        * the interrupts managed by the interrupt controller. 
     577+         */ 
     578+        if(irq_nr >= AVALANCHE_INTC_END) 
     579+        { 
     580+            if(irq_nr >= AVALANCHE_INT_END_LOW_VLYNQ) 
     581+                /* Vlynq interrupts 32-63 */ 
     582+                vlynq_interrupt_enable(&vlynqDevice1,VLYNQ_REMOTE_DVC, 
     583+                                      irq_nr-AVALANCHE_INT_END_LOW_VLYNQ); 
     584+            else 
     585+                /* Vlynq interupts 0-31 */ 
     586+                vlynq_interrupt_enable(&vlynqDevice0,VLYNQ_REMOTE_DVC, 
     587+                                      irq_nr-AVALANCHE_INTC_END); 
     588+ 
     589+            goto ret_from_enable_irq; 
     590+        } 
     591+#endif 
     592+ 
    477593+       /* irq_nr represents the line number for the interrupt.  We must 
    478594+        *  disable the channel number associated with that line number. 
     
    497613+       else    /* secondary interrupt #'s 0-31 */ 
    498614+               avalanche_hw0_ecregs->exiesr = (1 << (chan_nr - AVINTNUM(AVALANCHE_INT_END_PRIMARY))); 
     615+ 
     616+#if defined (CONFIG_AR7_VLYNQ) 
     617+ret_from_enable_irq: 
     618+#endif 
    499619+ 
    500620+       restore_flags(flags); 
     
    610730+ 
    611731+       if (irq > AVALANCHE_INT_END) { 
    612 +               printk("Trying to free IRQ%d\n",irq); 
     732+               printk(KERN_ERR "Trying to free IRQ%d\n",irq); 
    613733+               return; 
    614734+       } 
     
    668788+       // avalanche_hw0_ipaceregs->ipacep = (2*get_avalanche_vbus_freq()/1000000)*4; 
    669789+       /* hack for speeding up the pacing. */ 
    670 +       printk("the pacing pre-scalar has been set as 600.\n"); 
     790+       printk(KERN_INFO "the pacing pre-scalar has been set as 600.\n"); 
    671791+       avalanche_hw0_ipaceregs->ipacep = 600; 
    672792+       /* Channel to line mapping, Line to Channel mapping */ 
     
    767887+ 
    768888+       if ( action == NULL ) { 
    769 +               printk("No handler for hw0 irq: %i\n", irq); 
     889+               printk(KERN_ERR "No handler for hw0 irq: %i\n", irq); 
    770890+               return; 
    771891+       } 
     
    9161036+                       break; 
    9171037+               default: 
    918 +                       printk("Error: Unknown Avalanche interrupt channel\n"); 
     1038+                       printk(KERN_ERR "Error: Unknown Avalanche interrupt channel\n"); 
    9191039+       } 
    9201040+ 
     
    9661086+    return(0); 
    9671087+} 
    968 diff -urN linux.old/arch/mips/ar7/Makefile linux.dev/arch/mips/ar7/Makefile 
    969 --- linux.old/arch/mips/ar7/Makefile    1970-01-01 01:00:00.000000000 +0100 
    970 +++ linux.dev/arch/mips/ar7/Makefile    2005-08-12 21:21:30.425150040 +0200 
    971 @@ -0,0 +1,14 @@ 
    972 +.S.s: 
    973 +       $(CPP) $(AFLAGS) $< -o $*.s 
    974 + 
    975 +.S.o: 
    976 +       $(CC) $(AFLAGS) -c $< -o $*.o 
    977 + 
    978 +EXTRA_CFLAGS := -I$(TOPDIR)/include/asm/ar7 -DLITTLE_ENDIAN -D_LINK_KSEG0_ 
    979 +O_TARGET := ar7.o 
    980 + 
    981 +obj-y := tnetd73xx_misc.o misc.o 
    982 +export-objs := misc.o 
    983 +obj-y += setup.o irq.o mipsIRQ.o reset.o init.o psp_env.o memory.o printf.o cmdline.o time.o 
    984 + 
    985 +include $(TOPDIR)/Rules.make 
     1088+ 
     1089+/* Sets the trigger type: edge or level */ 
     1090+int avalanche_intr_type_set(unsigned int irq_nr, unsigned long type_val) 
     1091+{ 
     1092+    unsigned long flags; 
     1093+    unsigned long chan_nr=0; 
     1094+ 
     1095+    printk(KERN_NOTICE "AVALANCHE_INT_END_PRIMARY %d\n", 
     1096+          AVALANCHE_INT_END_PRIMARY); 
     1097+    printk(KERN_NOTICE "AVALANCHE_INT_END_SECONDARY %d\n", 
     1098+          AVALANCHE_INT_END_SECONDARY); 
     1099+    printk(KERN_NOTICE "AVALANCHE_INT_END %d\n", AVALANCHE_INT_END); 
     1100+    printk(KERN_NOTICE "AVALANCHE_INTC_END %d\n", AVALANCHE_INTC_END); 
     1101+    if(irq_nr  <  MIPS_EXCEPTION_OFFSET || 
     1102+       irq_nr  >= AVALANCHE_INT_END) 
     1103+    { 
     1104+        printk(KERN_ERR "%s: whee, invalid irq_nr %d\n", 
     1105+              __FUNCTION__, irq_nr); 
     1106+        panic("IRQ, you lose..."); 
     1107+        return(-1); 
     1108+    } 
     1109+ 
     1110+    if(type_val > 1) 
     1111+    { 
     1112+        printk(KERN_ERR "Not a valid polarity value.\n"); 
     1113+        return(-1); 
     1114+    } 
     1115+ 
     1116+#if defined (CONFIG_AR7_VLYNQ) 
     1117+    /* Vlynq irq_nr are 80-143 in the system and are placed after the interrupts 
     1118+     * managed by the interrupt controller. 
     1119+     */ 
     1120+    if(irq_nr >= AVALANCHE_INTC_END) 
     1121+    { 
     1122+        /* Type values for VLYNQ are INTC are different. */ 
     1123+        if(irq_nr >= AVALANCHE_INT_END_LOW_VLYNQ) 
     1124+            /* Vlynq interrupts 32-63 */ 
     1125+            vlynq_interrupt_set_type(&vlynqDevice1, VLYNQ_REMOTE_DVC, 
     1126+                                     irq_nr - AVALANCHE_INT_END_LOW_VLYNQ, !type_val); 
     1127+        else 
     1128+            /* Vlynq interupts 0-31 */ 
     1129+            vlynq_interrupt_set_type(&vlynqDevice0, VLYNQ_REMOTE_DVC, 
     1130+                                     irq_nr - AVALANCHE_INTC_END, !type_val); 
     1131+ 
     1132+        goto ret_from_set_type; 
     1133+    } 
     1134+#endif 
     1135+ 
     1136+    irq_nr = AVINTNUM(irq_nr); 
     1137+ 
     1138+    chan_nr = line_to_channel[AVINTNUM(irq_nr)]; 
     1139+ 
     1140+    save_and_cli(flags); 
     1141+ 
     1142+    /* primary interrupt #'s 0-31 */ 
     1143+    if(chan_nr < AVALANCHE_INT_END_PRIMARY_REG1) 
     1144+    { 
     1145+        if(type_val) 
     1146+            avalanche_hw0_icregs->inttypr1 |=  (1 << chan_nr); 
     1147+        else 
     1148+            avalanche_hw0_icregs->inttypr1 &= ~(1 << chan_nr); 
     1149+    } 
     1150+    /* primary interrupt #'s 32 throuth 39 */ 
     1151+    else 
     1152+    { 
     1153+        if(type_val) 
     1154+            avalanche_hw0_icregs->inttypr2 |= 
     1155+                (1 << (chan_nr - AVALANCHE_INT_END_PRIMARY_REG1)); 
     1156+        else 
     1157+            avalanche_hw0_icregs->inttypr2 &= 
     1158+                ~(1 << (chan_nr - AVALANCHE_INT_END_PRIMARY_REG1)); 
     1159+    } 
     1160+ 
     1161+    restore_flags(flags); 
     1162+ 
     1163+#if defined (CONFIG_AR7_VLYNQ) 
     1164+ret_from_set_type: 
     1165+#endif 
     1166+ 
     1167+    return(0); 
     1168+} 
     1169+ 
     1170+ 
     1171+int avalanche_intr_polarity_set(unsigned int irq_nr, unsigned long polarity_val) 
     1172+{ 
     1173+    unsigned long flags; 
     1174+    unsigned long chan_nr=0; 
     1175+ 
     1176+    if(irq_nr  <  MIPS_EXCEPTION_OFFSET || 
     1177+       irq_nr  >= AVALANCHE_INT_END) 
     1178+    { 
     1179+        printk(KERN_ERR "%s: whee, invalid irq_nr %d\n", 
     1180+              __FUNCTION__, irq_nr); 
     1181+#if defined (CONFIG_AR7_VLYNQ) 
     1182+        printk(KERN_ERR "Not one of the primary or vlynq avalanche interrupts.\n"); 
     1183+#else 
     1184+        printk(KERN_ERR "Not one of the primary avalanche interrupts\n"); 
     1185+#endif 
     1186+        panic("IRQ, you lose..."); 
     1187+        return(-1); 
     1188+    } 
     1189+ 
     1190+    if(polarity_val > 1) 
     1191+    { 
     1192+        printk(KERN_ERR "Not a valid polarity value.\n"); 
     1193+        return(-1); 
     1194+    } 
     1195+ 
     1196+ 
     1197+#if defined (CONFIG_AR7_VLYNQ) 
     1198+    /* Vlynq irq_nr are 80-143 in the system and are placed after the interrupts 
     1199+     * managed by the interrupt controller. 
     1200+     */ 
     1201+    if(irq_nr >= AVALANCHE_INTC_END) 
     1202+    { 
     1203+        if(irq_nr >= AVALANCHE_INT_END_LOW_VLYNQ) 
     1204+            /* Vlynq interrupts 32-63 */ 
     1205+            vlynq_interrupt_set_polarity(&vlynqDevice1, VLYNQ_REMOTE_DVC, 
     1206+                                         irq_nr - AVALANCHE_INT_END_LOW_VLYNQ, polarity_val); 
     1207+        else 
     1208+            /* Vlynq interupts 0-31 */ 
     1209+            vlynq_interrupt_set_polarity(&vlynqDevice0, VLYNQ_REMOTE_DVC, 
     1210+                                         irq_nr - AVALANCHE_INTC_END, polarity_val); 
     1211+        goto ret_from_set_polarity; 
     1212+    } 
     1213+#endif 
     1214+ 
     1215+    irq_nr = AVINTNUM(irq_nr); 
     1216+ 
     1217+    chan_nr = line_to_channel[irq_nr]; 
     1218+ 
     1219+    save_and_cli(flags); 
     1220+ 
     1221+    /* primary interrupt #'s 0-31 */ 
     1222+    if(chan_nr < AVALANCHE_INT_END_PRIMARY_REG1) 
     1223+    { 
     1224+        if(polarity_val) 
     1225+            avalanche_hw0_icregs->intpolr1 |=  (1 << chan_nr); 
     1226+        else 
     1227+            avalanche_hw0_icregs->intpolr1 &= ~(1 << chan_nr); 
     1228+    } 
     1229+    /* primary interrupt #'s 32 throuth 39 */ 
     1230+    else 
     1231+    { 
     1232+        if(polarity_val) 
     1233+            avalanche_hw0_icregs->intpolr2 |= 
     1234+                (1 << (chan_nr - AVALANCHE_INT_END_PRIMARY_REG1)); 
     1235+        else 
     1236+            avalanche_hw0_icregs->intpolr2 &= 
     1237+                ~(1 << (chan_nr - AVALANCHE_INT_END_PRIMARY_REG1)); 
     1238+    } 
     1239+ 
     1240+    restore_flags(flags); 
     1241+ 
     1242+#if defined (CONFIG_AR7_VLYNQ) 
     1243+ret_from_set_polarity: 
     1244+#endif 
     1245+ 
     1246+    return(0); 
     1247+} 
     1248+ 
     1249+EXPORT_SYMBOL(avalanche_intr_polarity_set); 
     1250+EXPORT_SYMBOL(avalanche_intr_type_set); 
    9861251diff -urN linux.old/arch/mips/ar7/memory.c linux.dev/arch/mips/ar7/memory.c 
    9871252--- linux.old/arch/mips/ar7/memory.c    1970-01-01 01:00:00.000000000 +0100 
    988 +++ linux.dev/arch/mips/ar7/memory.c    2005-08-12 19:52:25.301732312 +0200 
     1253+++ linux.dev/arch/mips/ar7/memory.c    2005-10-21 16:45:42.090061750 +0200 
    9891254@@ -0,0 +1,131 @@ 
    9901255+/* 
     
    11211386diff -urN linux.old/arch/mips/ar7/mipsIRQ.S linux.dev/arch/mips/ar7/mipsIRQ.S 
    11221387--- linux.old/arch/mips/ar7/mipsIRQ.S   1970-01-01 01:00:00.000000000 +0100 
    1123 +++ linux.dev/arch/mips/ar7/mipsIRQ.S   2005-08-12 19:32:05.138225360 +0200 
     1388+++ linux.dev/arch/mips/ar7/mipsIRQ.S   2005-10-21 16:45:42.118063500 +0200 
    11241389@@ -0,0 +1,120 @@ 
    11251390+/* 
     
    12451510diff -urN linux.old/arch/mips/ar7/misc.c linux.dev/arch/mips/ar7/misc.c 
    12461511--- linux.old/arch/mips/ar7/misc.c      1970-01-01 01:00:00.000000000 +0100 
    1247 +++ linux.dev/arch/mips/ar7/misc.c      2005-08-12 19:32:05.136225664 +0200 
     1512+++ linux.dev/arch/mips/ar7/misc.c      2005-10-21 16:45:42.122063750 +0200 
    12481513@@ -0,0 +1,319 @@ 
    12491514+#include <asm/ar7/sangam.h> 
     
    15681833diff -urN linux.old/arch/mips/ar7/platform.h linux.dev/arch/mips/ar7/platform.h 
    15691834--- linux.old/arch/mips/ar7/platform.h  1970-01-01 01:00:00.000000000 +0100 
    1570 +++ linux.dev/arch/mips/ar7/platform.h  2005-08-12 19:34:07.216666616 +0200 
     1835+++ linux.dev/arch/mips/ar7/platform.h  2005-10-21 16:45:42.122063750 +0200 
    15711836@@ -0,0 +1,65 @@ 
    15721837+#ifndef _PLATFORM_H_ 
     
    16371902diff -urN linux.old/arch/mips/ar7/printf.c linux.dev/arch/mips/ar7/printf.c 
    16381903--- linux.old/arch/mips/ar7/printf.c    1970-01-01 01:00:00.000000000 +0100 
    1639 +++ linux.dev/arch/mips/ar7/printf.c    2005-08-12 19:32:05.139225208 +0200 
     1904+++ linux.dev/arch/mips/ar7/printf.c    2005-10-21 16:45:42.122063750 +0200 
    16401905@@ -0,0 +1,53 @@ 
    16411906+/* 
     
    16941959diff -urN linux.old/arch/mips/ar7/psp_env.c linux.dev/arch/mips/ar7/psp_env.c 
    16951960--- linux.old/arch/mips/ar7/psp_env.c   1970-01-01 01:00:00.000000000 +0100 
    1696 +++ linux.dev/arch/mips/ar7/psp_env.c   2005-08-12 19:34:07.216666616 +0200 
     1961+++ linux.dev/arch/mips/ar7/psp_env.c   2005-10-21 16:45:42.122063750 +0200 
    16971962@@ -0,0 +1,350 @@ 
    16981963+#include <linux/config.h> 
     
    20482313diff -urN linux.old/arch/mips/ar7/reset.c linux.dev/arch/mips/ar7/reset.c 
    20492314--- linux.old/arch/mips/ar7/reset.c     1970-01-01 01:00:00.000000000 +0100 
    2050 +++ linux.dev/arch/mips/ar7/reset.c     2005-08-12 19:32:05.139225208 +0200 
     2315+++ linux.dev/arch/mips/ar7/reset.c     2005-10-21 16:45:42.122063750 +0200 
    20512316@@ -0,0 +1,56 @@ 
    20522317+/* 
     
    21082373diff -urN linux.old/arch/mips/ar7/setup.c linux.dev/arch/mips/ar7/setup.c 
    21092374--- linux.old/arch/mips/ar7/setup.c     1970-01-01 01:00:00.000000000 +0100 
    2110 +++ linux.dev/arch/mips/ar7/setup.c     2005-08-12 19:32:05.139225208 +0200 
     2375+++ linux.dev/arch/mips/ar7/setup.c     2005-10-21 16:45:42.122063750 +0200 
    21112376@@ -0,0 +1,120 @@ 
    21122377+/* 
     
    22322497diff -urN linux.old/arch/mips/ar7/time.c linux.dev/arch/mips/ar7/time.c 
    22332498--- linux.old/arch/mips/ar7/time.c      1970-01-01 01:00:00.000000000 +0100 
    2234 +++ linux.dev/arch/mips/ar7/time.c      2005-08-12 23:34:00.272589528 +0200 
     2499+++ linux.dev/arch/mips/ar7/time.c      2005-10-21 16:45:42.126064000 +0200 
    22352500@@ -0,0 +1,124 @@ 
    22362501+/* 
     
    23602625diff -urN linux.old/arch/mips/ar7/tnetd73xx_misc.c linux.dev/arch/mips/ar7/tnetd73xx_misc.c 
    23612626--- linux.old/arch/mips/ar7/tnetd73xx_misc.c    1970-01-01 01:00:00.000000000 +0100 
    2362 +++ linux.dev/arch/mips/ar7/tnetd73xx_misc.c    2005-08-12 19:32:05.140225056 +0200 
     2627+++ linux.dev/arch/mips/ar7/tnetd73xx_misc.c    2005-10-21 16:45:42.126064000 +0200 
    23632628@@ -0,0 +1,924 @@ 
    23642629+/****************************************************************************** 
     
    32873552+ 
    32883553diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared.in 
    3289 --- linux.old/arch/mips/config-shared.in        2005-07-10 03:00:44.000000000 +0200 
    3290 +++ linux.dev/arch/mips/config-shared.in        2005-08-12 19:53:15.060167880 +0200 
     3554--- linux.old/arch/mips/config-shared.in        2005-10-21 16:43:18.917114000 +0200 
     3555+++ linux.dev/arch/mips/config-shared.in        2005-10-21 16:45:42.126064000 +0200 
    32913556@@ -20,6 +20,16 @@ 
    32923557 mainmenu_option next_comment 
     
    33343599      "$CONFIG_IBM_WORKPAD" = "y" -o \ 
    33353600diff -urN linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S 
    3336 --- linux.old/arch/mips/kernel/head.S   2005-07-10 02:55:18.000000000 +0200 
    3337 +++ linux.dev/arch/mips/kernel/head.S   2005-08-12 23:05:36.954533232 +0200 
     3601--- linux.old/arch/mips/kernel/head.S   2005-10-21 16:43:16.396956500 +0200 
     3602+++ linux.dev/arch/mips/kernel/head.S   2005-10-21 16:45:42.126064000 +0200 
    33383603@@ -75,11 +75,11 @@ 
    33393604                 * size! 
     
    33543619                /* 
    33553620diff -urN linux.old/arch/mips/kernel/irq.c linux.dev/arch/mips/kernel/irq.c 
    3356 --- linux.old/arch/mips/kernel/irq.c    2005-07-10 03:00:44.000000000 +0200 
    3357 +++ linux.dev/arch/mips/kernel/irq.c    2005-08-12 19:32:05.142224752 +0200 
     3621--- linux.old/arch/mips/kernel/irq.c    2004-02-18 14:36:30.000000000 +0100 
     3622+++ linux.dev/arch/mips/kernel/irq.c    2005-10-21 16:45:42.130064250 +0200 
    33583623@@ -76,6 +76,7 @@ 
    33593624  * Generic, controller-independent functions: 
     
    34063671diff -urN linux.old/arch/mips/kernel/mips_ksyms.c linux.dev/arch/mips/kernel/mips_ksyms.c 
    34073672--- linux.old/arch/mips/kernel/mips_ksyms.c     2004-02-18 14:36:30.000000000 +0100 
    3408 +++ linux.dev/arch/mips/kernel/mips_ksyms.c     2005-08-12 19:32:05.142224752 +0200 
     3673+++ linux.dev/arch/mips/kernel/mips_ksyms.c     2005-10-21 17:02:14.507635750 +0200 
    34093674@@ -40,6 +40,12 @@ 
    34103675 extern long __strnlen_user_nocheck_asm(const char *s); 
     
    34123677  
    34133678+#ifdef CONFIG_AR7 
     3679+#include <asm/ar7/adam2_env.h> 
    34143680+int avalanche_request_pacing(int irq_nr, unsigned int blk_num, unsigned int pace_value); 
    3415 +char *prom_getenv(char *envname); 
    34163681+#endif 
    34173682+ 
     
    34203685 #ifdef CONFIG_EISA 
    34213686 EXPORT_SYMBOL(EISA_bus); 
    3422 @@ -103,3 +109,9 @@ 
     3687@@ -103,3 +109,10 @@ 
    34233688 #endif 
    34243689  
     
    34283693+EXPORT_SYMBOL_NOVERS(avalanche_request_pacing); 
    34293694+EXPORT_SYMBOL_NOVERS(prom_getenv); 
     3695+EXPORT_SYMBOL_NOVERS(prom_iterenv); 
    34303696+#endif 
    34313697+ 
    34323698diff -urN linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c 
    3433 --- linux.old/arch/mips/kernel/setup.c  2005-07-10 03:00:44.000000000 +0200 
    3434 +++ linux.dev/arch/mips/kernel/setup.c  2005-08-12 19:56:27.917849056 +0200 
     3699--- linux.old/arch/mips/kernel/setup.c  2005-10-21 16:43:16.396956500 +0200 
     3700+++ linux.dev/arch/mips/kernel/setup.c  2005-10-21 16:45:42.130064250 +0200 
    34353701@@ -235,7 +235,11 @@ 
    34363702 #define PFN_DOWN(x)    ((x) >> PAGE_SHIFT) 
     
    34793745        } 
    34803746diff -urN linux.old/arch/mips/kernel/traps.c linux.dev/arch/mips/kernel/traps.c 
    3481 --- linux.old/arch/mips/kernel/traps.c  2005-07-10 03:00:44.000000000 +0200 
    3482 +++ linux.dev/arch/mips/kernel/traps.c  2005-08-12 23:38:46.505075576 +0200 
     3747--- linux.old/arch/mips/kernel/traps.c  2005-10-21 16:43:16.400956750 +0200 
     3748+++ linux.dev/arch/mips/kernel/traps.c  2005-10-21 16:45:42.130064250 +0200 
    34833749@@ -869,9 +869,15 @@ 
    34843750  
     
    35113777  
    35123778diff -urN linux.old/arch/mips/lib/promlib.c linux.dev/arch/mips/lib/promlib.c 
    3513 --- linux.old/arch/mips/lib/promlib.c   2005-07-10 03:00:44.000000000 +0200 
    3514 +++ linux.dev/arch/mips/lib/promlib.c   2005-08-12 20:39:57.087195024 +0200 
     3779--- linux.old/arch/mips/lib/promlib.c   2003-08-25 13:44:40.000000000 +0200 
     3780+++ linux.dev/arch/mips/lib/promlib.c   2005-10-21 16:45:42.130064250 +0200 
    35153781@@ -1,6 +1,8 @@ 
    35163782 #include <stdarg.h> 
     
    35273793 } 
    35283794+#endif 
    3529 diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile 
    3530 --- linux.old/arch/mips/Makefile        2005-07-10 03:00:44.000000000 +0200 
    3531 +++ linux.dev/arch/mips/Makefile        2005-08-12 20:38:28.398677728 +0200 
    3532 @@ -369,6 +369,16 @@ 
    3533  endif 
    3534   
    3535  # 
    3536 +# Texas Instruments AR7 
    3537 +# 
    3538 + 
    3539 +ifdef CONFIG_AR7 
    3540 +LIBS           += arch/mips/ar7/ar7.o 
    3541 +SUBDIRS                += arch/mips/ar7 
    3542 +LOADADDR       += 0x94020000 
    3543 +endif 
    3544 + 
    3545 +# 
    3546  # DECstation family 
    3547  # 
    3548  ifdef CONFIG_DECSTATION 
    35493795diff -urN linux.old/arch/mips/mm/init.c linux.dev/arch/mips/mm/init.c 
    3550 --- linux.old/arch/mips/mm/init.c       2005-07-10 03:00:44.000000000 +0200 
    3551 +++ linux.dev/arch/mips/mm/init.c       2005-08-12 21:08:04.420681344 +0200 
     3796--- linux.old/arch/mips/mm/init.c       2004-02-18 14:36:30.000000000 +0100 
     3797+++ linux.dev/arch/mips/mm/init.c       2005-10-21 16:45:42.134064500 +0200 
    35523798@@ -248,6 +248,9 @@ 
    35533799  
     
    36063852  
    36073853        reservedpages = ram = 0; 
     3854diff -urN linux.old/drivers/char/Config.in linux.dev/drivers/char/Config.in 
     3855--- linux.old/drivers/char/Config.in    2005-10-21 16:43:16.440959250 +0200 
     3856+++ linux.dev/drivers/char/Config.in    2005-10-21 17:02:20.199991500 +0200 
     3857@@ -188,6 +188,14 @@ 
     3858    tristate 'Total Impact briQ front panel driver' CONFIG_BRIQ_PANEL 
     3859 fi 
     3860  
     3861+if [ "$CONFIG_AR7" = "y" ]; then   
     3862+   bool 'VLYNQ support for the TI SOC' CONFIG_AR7_VLYNQ 
     3863+   dep_bool 'VLYNQ clock source Internal' CONFIG_VLYNQ_CLK_LOCAL $CONFIG_AR7_VLYNQ 
     3864+                    
     3865+   define_int CONFIG_AR7_VLYNQ_PORTS 2  
     3866+   tristate 'ADAM2 environment support (read-only)' CONFIG_AR7_ADAM2 
     3867+fi                                                                                              
     3868+ 
     3869 source drivers/i2c/Config.in 
     3870  
     3871 mainmenu_option next_comment 
     3872diff -urN linux.old/drivers/char/Config.in.orig linux.dev/drivers/char/Config.in.orig 
     3873--- linux.old/drivers/char/Config.in.orig       1970-01-01 01:00:00.000000000 +0100 
     3874+++ linux.dev/drivers/char/Config.in.orig       2005-10-21 16:45:47.854422000 +0200 
     3875@@ -0,0 +1,414 @@ 
     3876+# 
     3877+# Character device configuration 
     3878+# 
     3879+mainmenu_option next_comment 
     3880+comment 'Character devices' 
     3881+ 
     3882+bool 'Virtual terminal' CONFIG_VT 
     3883+if [ "$CONFIG_VT" = "y" ]; then 
     3884+   bool '  Support for console on virtual terminal' CONFIG_VT_CONSOLE 
     3885+   if [ "$CONFIG_GSC_LASI" = "y" ]; then 
     3886+      bool '    Support for Lasi/Dino PS2 port' CONFIG_GSC_PS2 
     3887+   fi 
     3888+fi 
     3889+tristate 'Standard/generic (8250/16550 and compatible UARTs) serial support' CONFIG_SERIAL 
     3890+if [ "$CONFIG_SERIAL" = "y" ]; then 
     3891+   bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE 
     3892+   if [ "$CONFIG_GSC_LASI" = "y" ]; then 
     3893+      bool '   serial port on GSC support' CONFIG_SERIAL_GSC 
     3894+   fi 
     3895+   if [ "$CONFIG_IA64" = "y" ]; then 
     3896+      bool '  Support for serial port described by EFI HCDP table' CONFIG_SERIAL_HCDP 
     3897+   fi 
     3898+   if [ "$CONFIG_ARCH_ACORN" = "y" ]; then 
     3899+      tristate '   Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL 
     3900+      tristate '   Dual serial port support' CONFIG_DUALSP_SERIAL 
     3901+   fi 
     3902+fi 
     3903+dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL 
     3904+if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then 
     3905+   bool '  Support more than 4 serial ports' CONFIG_SERIAL_MANY_PORTS 
     3906+   bool '  Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ 
     3907+   bool '  Autodetect IRQ on standard ports (unsafe)' CONFIG_SERIAL_DETECT_IRQ 
     3908+   bool '  Support special multiport boards' CONFIG_SERIAL_MULTIPORT 
     3909+   bool '  Support the Bell Technologies HUB6 card' CONFIG_HUB6 
     3910+fi 
     3911+bool 'Non-standard serial port support' CONFIG_SERIAL_NONSTANDARD 
     3912+if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then 
     3913+   tristate '  Computone IntelliPort Plus serial support' CONFIG_COMPUTONE 
     3914+   tristate '  Comtrol Rocketport support' CONFIG_ROCKETPORT 
     3915+   tristate '  Cyclades async mux support' CONFIG_CYCLADES 
     3916+   if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_CYCLADES" != "n" ]; then 
     3917+      bool '    Cyclades-Z interrupt mode operation (EXPERIMENTAL)' CONFIG_CYZ_INTR 
     3918+   fi 
     3919+   if [ "$CONFIG_X86_64" != "y" ]; then 
     3920+      tristate '  Digiboard Intelligent Async Support' CONFIG_DIGIEPCA 
     3921+      if [ "$CONFIG_DIGIEPCA" = "n" ]; then 
     3922+         tristate '  Digiboard PC/Xx Support' CONFIG_DIGI 
     3923+      fi 
     3924+   fi 
     3925+   dep_tristate '  Hayes ESP serial port support' CONFIG_ESPSERIAL $CONFIG_ISA 
     3926+   tristate '  Moxa Intellio support' CONFIG_MOXA_INTELLIO 
     3927+   tristate '  Moxa SmartIO support' CONFIG_MOXA_SMARTIO 
     3928+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then 
     3929+      dep_tristate '  Multi-Tech multiport card support (EXPERIMENTAL)' CONFIG_ISI m 
     3930+   fi 
     3931+   tristate '  Microgate SyncLink card support' CONFIG_SYNCLINK 
     3932+   tristate '  SyncLink Multiport support' CONFIG_SYNCLINKMP 
     3933+   tristate '  HDLC line discipline support' CONFIG_N_HDLC 
     3934+   tristate '  SDL RISCom/8 card support' CONFIG_RISCOM8 
     3935+   if [ "$CONFIG_X86_64" != "y" ]; then 
     3936+      tristate '  Specialix IO8+ card support' CONFIG_SPECIALIX 
     3937+      if [ "$CONFIG_SPECIALIX" != "n" ]; then 
     3938+         bool '  Specialix DTR/RTS pin is RTS' CONFIG_SPECIALIX_RTSCTS 
     3939+      fi  
     3940+      tristate '  Specialix SX (and SI) card support' CONFIG_SX 
     3941+      tristate '  Specialix RIO system support' CONFIG_RIO 
     3942+      if [ "$CONFIG_RIO" != "n" ]; then 
     3943+        bool '    Support really old RIO/PCI cards' CONFIG_RIO_OLDPCI 
     3944+      fi 
     3945+   fi 
     3946+   bool '  Stallion multiport serial support' CONFIG_STALDRV 
     3947+   if [ "$CONFIG_STALDRV" = "y" ]; then 
     3948+     tristate '    Stallion EasyIO or EC8/32 support' CONFIG_STALLION 
     3949+     tristate '    Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION 
     3950+   fi 
     3951+   if [ "$CONFIG_PARISC" = "y" ]; then 
     3952+     if [ "$CONFIG_PDC_CONSOLE" != "y" ]; then 
     3953+       bool '  Serial MUX support' CONFIG_SERIAL_MUX CONFIG_SERIAL_NONSTANDARD 
     3954+     fi 
     3955+     if [ "$CONFIG_SERIAL_MUX" != "y" ]; then 
     3956+       bool '  PDC software console support' CONFIG_PDC_CONSOLE CONFIG_SERIAL_NONSTANDARD 
     3957+     fi 
     3958+   fi 
     3959+   if [ "$CONFIG_MIPS" = "y" ]; then 
     3960+      bool '  TX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912 
     3961+      dep_bool '     Console on TX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912 
     3962+      bool '  TMPTX39XX/49XX serial port support' CONFIG_SERIAL_TXX9 
     3963+      dep_bool '     Console on TMPTX39XX/49XX serial port' CONFIG_SERIAL_TXX9_CONSOLE $CONFIG_SERIAL_TXX9 
     3964+      if [ "$CONFIG_SOC_AU1X00" = "y" ]; then 
     3965+        bool '  Enable Au1x00 UART Support' CONFIG_AU1X00_UART 
     3966+        if [ "$CONFIG_AU1X00_UART" = "y" ]; then 
     3967+           bool '        Enable Au1x00 serial console' CONFIG_AU1X00_SERIAL_CONSOLE 
     3968+         fi 
     3969+         dep_tristate '  Au1x00 USB TTY Device support' CONFIG_AU1X00_USB_TTY $CONFIG_SOC_AU1X00 
     3970+           if [ "$CONFIG_AU1000_USB_TTY" != "y" ]; then 
     3971+              dep_tristate '  Au1x00 USB Raw Device support' CONFIG_AU1X00_USB_RAW $CONFIG_SOC_AU1X00 
     3972+           fi 
     3973+           if [ "$CONFIG_AU1X00_USB_TTY" != "n" -o \ 
     3974+                "$CONFIG_AU1X00_USB_RAW" != "n" ]; then 
     3975+                define_bool CONFIG_AU1X00_USB_DEVICE y 
     3976+           fi 
     3977+      fi 
     3978+      bool '  TXx927 SIO support' CONFIG_TXX927_SERIAL  
     3979+      if [ "$CONFIG_TXX927_SERIAL" = "y" ]; then 
     3980+         bool '    TXx927 SIO Console support' CONFIG_TXX927_SERIAL_CONSOLE   
     3981+      fi                              
     3982+      if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then 
     3983+         bool '  Support for BCM1xxx onchip DUART' CONFIG_SIBYTE_SB1250_DUART 
     3984+         if [ "$CONFIG_SIBYTE_SB1250_DUART" = "y" ]; then 
     3985+            bool '    Console on BCM1xxx DUART' CONFIG_SIBYTE_SB1250_DUART_CONSOLE 
     3986+            if [ "$CONFIG_SIBYTE_SB1250_DUART_CONSOLE" = "y" ]; then 
     3987+               define_bool CONFIG_SERIAL_CONSOLE y 
     3988+            fi 
     3989+         fi 
     3990+      fi 
     3991+   fi 
     3992+   if [ "$CONFIG_DECSTATION" = "y" ]; then 
     3993+      bool '  DECstation serial support' CONFIG_SERIAL_DEC 
     3994+      dep_bool '    Support for console on a DECstation serial port' CONFIG_SERIAL_DEC_CONSOLE $CONFIG_SERIAL_DEC 
     3995+      dep_bool '    DZ11 serial support' CONFIG_DZ $CONFIG_SERIAL_DEC $CONFIG_MIPS32 
     3996+      dep_bool '    Z85C30 serial support' CONFIG_ZS $CONFIG_SERIAL_DEC $CONFIG_TC 
     3997+   fi 
     3998+   if [ "$CONFIG_SGI_IP22" = "y" ]; then 
     3999+      bool '  SGI Zilog85C30 serial support' CONFIG_IP22_SERIAL 
     4000+   fi 
     4001+   if [ "$CONFIG_IA64" = "y" ]; then 
     4002+      bool '  SGI SN2 l1 serial port support' CONFIG_SGI_L1_SERIAL 
     4003+      if [ "$CONFIG_SGI_L1_SERIAL" = "y" ]; then 
     4004+        bool '    SGI SN2 l1 Console support' CONFIG_SGI_L1_SERIAL_CONSOLE 
     4005+      fi 
     4006+      if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then 
     4007+        bool '  SGI SN2 IOC4 serial port support' CONFIG_SGI_IOC4_SERIAL 
     4008+      fi 
     4009+   fi 
     4010+fi 
     4011+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then 
     4012+   tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232 
     4013+fi 
     4014+if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then 
     4015+   bool 'DC21285 serial port support' CONFIG_SERIAL_21285 
     4016+   if [ "$CONFIG_SERIAL_21285" = "y" ]; then 
     4017+      if [ "$CONFIG_OBSOLETE" = "y" ]; then 
     4018+         bool '  Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD 
     4019+      fi 
     4020+      bool '  Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE 
     4021+   fi 
     4022+   if [ "$CONFIG_PARISC" = "y" ]; then 
     4023+     bool '  PDC software console support' CONFIG_PDC_CONSOLE 
     4024+   fi 
     4025+fi 
     4026+if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then 
     4027+   bool 'Enable Qtronix 990P Keyboard Support' CONFIG_QTRONIX_KEYBOARD 
     4028+   if [ "$CONFIG_QTRONIX_KEYBOARD" = "y" ]; then 
     4029+     define_bool CONFIG_IT8172_CIR y 
     4030+   else 
     4031+     bool '    Enable PS2 Keyboard Support' CONFIG_PC_KEYB 
     4032+   fi 
     4033+   bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0 
     4034+   bool 'Enable Smart Card Reader 1 Support ' CONFIG_IT8172_SCR1 
     4035+fi 
     4036+if [ "$CONFIG_MIPS_IVR" = "y" ]; then 
     4037+   bool 'Enable Qtronix 990P Keyboard Support' CONFIG_QTRONIX_KEYBOARD 
     4038+   if [ "$CONFIG_QTRONIX_KEYBOARD" = "y" ]; then 
     4039+     define_bool CONFIG_IT8172_CIR y 
     4040+   fi 
     4041+   bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0 
     4042+fi 
     4043+if [ "$CONFIG_CPU_VR41XX" = "y" ]; then 
     4044+   bool 'NEC VR4100 series Keyboard Interface Unit Support ' CONFIG_VR41XX_KIU 
     4045+fi 
     4046+bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS 
     4047+if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then 
     4048+   int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 
     4049+fi 
     4050+if [ "$CONFIG_PARPORT" != "n" ]; then 
     4051+   dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT 
     4052+   if [ "$CONFIG_PRINTER" != "n" ]; then 
     4053+      bool '  Support for console on line printer' CONFIG_LP_CONSOLE 
     4054+   fi 
     4055+   dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT 
     4056+   dep_tristate 'Texas Instruments parallel link cable support' CONFIG_TIPAR $CONFIG_PARPORT 
     4057+fi 
     4058+ 
     4059+if [ "$CONFIG_PPC64" = "y" ] ; then  
     4060+   bool 'pSeries Hypervisor Virtual Console support' CONFIG_HVC_CONSOLE 
     4061+fi 
     4062+if [ "$CONFIG_ALL_PPC" = "y" ]; then 
     4063+   tristate 'Total Impact briQ front panel driver' CONFIG_BRIQ_PANEL 
     4064+fi 
     4065+ 
     4066+if [ "$CONFIG_AR7" = "y" ]; then   
     4067+   bool 'VLYNQ support for the TI SOC' CONFIG_AR7_VLYNQ 
     4068+   dep_bool 'VLYNQ clock source Internal' CONFIG_VLYNQ_CLK_LOCAL $CONFIG_AR7_VLYNQ 
     4069+                    
     4070+   define_int CONFIG_AR7_VLYNQ_PORTS 2  
     4071+fi                                                                                              
     4072+ 
     4073+source drivers/i2c/Config.in 
     4074+ 
     4075+mainmenu_option next_comment 
     4076+comment 'Mice' 
     4077+tristate 'Bus Mouse Support' CONFIG_BUSMOUSE 
     4078+if [ "$CONFIG_BUSMOUSE" != "n" ]; then 
     4079+   dep_tristate '  ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE $CONFIG_BUSMOUSE 
     4080+   dep_tristate '  Logitech busmouse support' CONFIG_LOGIBUSMOUSE $CONFIG_BUSMOUSE 
     4081+   dep_tristate '  Microsoft busmouse support' CONFIG_MS_BUSMOUSE $CONFIG_BUSMOUSE 
     4082+   if [ "$CONFIG_ADB" = "y" -a "$CONFIG_ADB_KEYBOARD" = "y" ]; then 
     4083+      dep_tristate '  Apple Desktop Bus mouse support (old driver)' CONFIG_ADBMOUSE $CONFIG_BUSMOUSE 
     4084+   fi 
     4085+#   if [ "$CONFIG_DECSTATION" = "y" ]; then 
     4086+#      dep_bool '  MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE $CONFIG_ACCESSBUS 
     4087+#   fi 
     4088+fi 
     4089+ 
     4090+tristate 'Mouse Support (not serial and bus mice)' CONFIG_MOUSE 
     4091+if [ "$CONFIG_MOUSE" != "n" ]; then 
     4092+   bool '  PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE 
     4093+   tristate '  C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE 
     4094+   tristate '  PC110 digitizer pad support' CONFIG_PC110_PAD 
     4095+   tristate '  MK712 touch screen support' CONFIG_MK712_MOUSE 
     4096+fi 
     4097+endmenu 
     4098+ 
     4099+source drivers/char/joystick/Config.in 
     4100+ 
     4101+tristate 'QIC-02 tape support' CONFIG_QIC02_TAPE 
     4102+if [ "$CONFIG_QIC02_TAPE" != "n" ]; then 
     4103+   bool '  Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF 
     4104+   if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then 
     4105+      comment '  Edit configuration parameters in ./include/linux/tpqic02.h!' 
     4106+   else 
     4107+      comment '  Setting runtime QIC-02 configuration is done with qic02conf' 
     4108+      comment '  from the tpqic02-support package.  It is available at' 
     4109+      comment '  metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/' 
     4110+   fi 
     4111+fi 
     4112+ 
     4113+tristate 'IPMI top-level message handler' CONFIG_IPMI_HANDLER 
     4114+dep_mbool '  Generate a panic event to all BMCs on a panic' CONFIG_IPMI_PANIC_EVENT $CONFIG_IPMI_HANDLER 
     4115+dep_tristate '  Device interface for IPMI' CONFIG_IPMI_DEVICE_INTERFACE $CONFIG_IPMI_HANDLER 
     4116+dep_tristate '  IPMI KCS handler' CONFIG_IPMI_KCS $CONFIG_IPMI_HANDLER 
     4117+dep_tristate '  IPMI Watchdog Timer' CONFIG_IPMI_WATCHDOG $CONFIG_IPMI_HANDLER 
     4118+ 
     4119+mainmenu_option next_comment 
     4120+comment 'Watchdog Cards' 
     4121+bool 'Watchdog Timer Support'  CONFIG_WATCHDOG 
     4122+if [ "$CONFIG_WATCHDOG" != "n" ]; then 
     4123+   bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT 
     4124+   tristate '  Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT 
     4125+   tristate '  Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT 
     4126+   tristate '  ALi M7101 PMU on ALi 1535D+ Watchdog Timer' CONFIG_ALIM1535_WDT 
     4127+   tristate '  ALi M7101 PMU Watchdog Timer' CONFIG_ALIM7101_WDT 
     4128+   tristate '  AMD "Elan" SC520 Watchdog Timer' CONFIG_SC520_WDT 
     4129+   tristate '  Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG 
     4130+   if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then 
     4131+      tristate '  DC21285 watchdog' CONFIG_21285_WATCHDOG 
     4132+      if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then 
     4133+         tristate '  NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG 
     4134+      fi 
     4135+   fi 
     4136+   tristate '  Eurotech CPU-1220/1410 Watchdog Timer' CONFIG_EUROTECH_WDT 
     4137+   tristate '  IB700 SBC Watchdog Timer' CONFIG_IB700_WDT 
     4138+   tristate '  ICP ELectronics Wafer 5823 Watchdog' CONFIG_WAFER_WDT 
     4139+   tristate '  Intel i810 TCO timer / Watchdog' CONFIG_I810_TCO 
     4140+   tristate '  Mixcom Watchdog' CONFIG_MIXCOMWD  
     4141+   tristate '  SBC-60XX Watchdog Timer' CONFIG_60XX_WDT 
     4142+   dep_tristate '  SC1200 Watchdog Timer (EXPERIMENTAL)' CONFIG_SC1200_WDT $CONFIG_EXPERIMENTAL 
     4143+   tristate '  NatSemi SCx200 Watchdog' CONFIG_SCx200_WDT 
     4144+   tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG 
     4145+   tristate '  W83877F (EMACS) Watchdog Timer' CONFIG_W83877F_WDT 
     4146+   tristate '  WDT Watchdog timer' CONFIG_WDT 
     4147+   tristate '  WDT PCI Watchdog timer' CONFIG_WDTPCI 
     4148+   if [ "$CONFIG_WDT" != "n" ]; then 
     4149+      bool '    WDT501 features' CONFIG_WDT_501 
     4150+      if [ "$CONFIG_WDT_501" = "y" ]; then 
     4151+         bool '      Fan Tachometer' CONFIG_WDT_501_FAN 
     4152+      fi 
     4153+   fi 
     4154+   tristate '  ZF MachZ Watchdog' CONFIG_MACHZ_WDT 
     4155+   if [ "$CONFIG_SGI_IP22" = "y" ]; then 
     4156+      dep_tristate '  Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22 
     4157+   fi 
     4158+   if [ "$CONFIG_8xx" = "y" ]; then 
     4159+      tristate '  MPC8xx Watchdog Timer' CONFIG_8xx_WDT 
     4160+   fi 
     4161+fi 
     4162+endmenu 
     4163+ 
     4164+if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then 
     4165+   tristate 'NetWinder thermometer support' CONFIG_DS1620 
     4166+   tristate 'NetWinder Button' CONFIG_NWBUTTON 
     4167+   if [ "$CONFIG_NWBUTTON" != "n" ]; then 
     4168+      bool '  Reboot Using Button' CONFIG_NWBUTTON_REBOOT 
     4169+   fi 
     4170+   tristate 'NetWinder flash support' CONFIG_NWFLASH 
     4171+fi 
     4172+tristate 'NatSemi SCx200 Support' CONFIG_SCx200 
     4173+dep_tristate '  NatSemi SCx200 GPIO Support' CONFIG_SCx200_GPIO $CONFIG_SCx200 
     4174+ 
     4175+if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ] ; then 
     4176+   bool 'SGI SN2 fetchop support' CONFIG_FETCHOP 
     4177+fi 
     4178+ 
     4179+if [ "$CONFIG_X86" = "y" -o "$CONFIG_X86_64" = "y" ]; then 
     4180+   dep_tristate 'AMD 768/8111 Random Number Generator support' CONFIG_AMD_RNG $CONFIG_PCI 
     4181+fi 
     4182+if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then 
     4183+   dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI 
     4184+fi 
     4185+if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" -o \ 
     4186+     "$CONFIG_X86_64" = "y" ]; then 
     4187+   dep_tristate 'Intel/AMD/VIA HW Random Number Generator support' CONFIG_HW_RANDOM $CONFIG_PCI 
     4188+fi 
     4189+dep_tristate 'AMD 76x native power management (Experimental)' CONFIG_AMD_PM768 $CONFIG_PCI 
     4190+tristate '/dev/nvram support' CONFIG_NVRAM 
     4191+tristate 'Enhanced Real Time Clock Support' CONFIG_RTC 
     4192+if [ "$CONFIG_IA64" = "y" ]; then 
     4193+   bool 'EFI Real Time Clock Services' CONFIG_EFI_RTC 
     4194+fi 
     4195+if [ "$CONFIG_OBSOLETE" = "y" -a "$CONFIG_ALPHA_BOOK1" = "y" ]; then 
     4196+   bool 'Tadpole ANA H8 Support (OBSOLETE)'  CONFIG_H8 
     4197+fi 
     4198+if [ "$CONFIG_SGI_IP22" = "y" ]; then 
     4199+   tristate 'Dallas DS1286 RTC support' CONFIG_DS1286 
     4200+fi 
     4201+if [ "$CONFIG_SGI_IP27" = "y" ]; then 
     4202+   tristate 'SGI M48T35 RTC support' CONFIG_SGI_IP27_RTC 
     4203+fi 
     4204+if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" -o "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then 
     4205+   tristate 'Dallas DS1742 RTC support' CONFIG_DS1742 
     4206+fi 
     4207+ 
     4208+tristate 'Double Talk PC internal speech card support' CONFIG_DTLK 
     4209+tristate 'Siemens R3964 line discipline' CONFIG_R3964 
     4210+tristate 'Applicom intelligent fieldbus card support' CONFIG_APPLICOM 
     4211+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_X86" = "y" -a "$CONFIG_X86_64" != "y" ]; then 
     4212+   dep_tristate 'Sony Vaio Programmable I/O Control Device support (EXPERIMENTAL)' CONFIG_SONYPI $CONFIG_PCI 
     4213+fi 
     4214+ 
     4215+mainmenu_option next_comment 
     4216+comment 'Ftape, the floppy tape device driver' 
     4217+tristate 'Ftape (QIC-80/Travan) support' CONFIG_FTAPE 
     4218+if [ "$CONFIG_FTAPE" != "n" ]; then 
     4219+   source drivers/char/ftape/Config.in 
     4220+fi 
     4221+ 
     4222+endmenu 
     4223+ 
     4224+if [ "$CONFIG_GART_IOMMU" = "y" ]; then 
     4225+       bool '/dev/agpgart (AGP Support)' CONFIG_AGP 
     4226+       define_bool CONFIG_AGP_AMD_K8 y 
     4227+else 
     4228+       tristate '/dev/agpgart (AGP Support)' CONFIG_AGP 
     4229+fi       
     4230+if [ "$CONFIG_AGP" != "n" ]; then 
     4231+   bool '  Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support' CONFIG_AGP_INTEL 
     4232+   bool '  Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810 
     4233+   bool '  VIA chipset support' CONFIG_AGP_VIA 
     4234+   bool '  AMD Irongate, 761, and 762 support' CONFIG_AGP_AMD 
     4235+   if [ "$CONFIG_GART_IOMMU" != "y" ]; then 
     4236+      bool '  AMD Opteron/Athlon64 on-CPU GART support' CONFIG_AGP_AMD_K8 
     4237+   fi    
     4238+   bool '  Generic SiS support' CONFIG_AGP_SIS 
     4239+   bool '  ALI chipset support' CONFIG_AGP_ALI 
     4240+   bool '  Serverworks LE/HE support' CONFIG_AGP_SWORKS 
     4241+   if [ "$CONFIG_X86" = "y" ]; then 
     4242+      bool '  NVIDIA chipset support' CONFIG_AGP_NVIDIA 
     4243+   fi 
     4244+   if [ "$CONFIG_IA64" = "y" ]; then 
     4245+      bool '  Intel 460GX support' CONFIG_AGP_I460 
     4246+      bool '  HP ZX1 AGP support' CONFIG_AGP_HP_ZX1 
     4247+   fi 
     4248+   bool '  ATI IGP chipset support' CONFIG_AGP_ATI 
     4249+fi 
     4250+ 
     4251+mainmenu_option next_comment 
     4252+comment 'Direct Rendering Manager (XFree86 DRI support)' 
     4253+bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM 
     4254+if [ "$CONFIG_DRM" = "y" ]; then 
     4255+   bool '  Build drivers for old (XFree 4.0) DRM' CONFIG_DRM_OLD 
     4256+   if [ "$CONFIG_DRM_OLD" = "y" ]; then 
     4257+      comment 'DRM 4.0 drivers' 
     4258+      source drivers/char/drm-4.0/Config.in 
     4259+   else 
     4260+      comment 'DRM 4.1 drivers' 
     4261+      define_bool CONFIG_DRM_NEW y 
     4262+      source drivers/char/drm/Config.in 
     4263+   fi 
     4264+fi 
     4265+ 
     4266+if [ "$CONFIG_X86" = "y" ]; then 
     4267+   tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE 
     4268+fi 
     4269+ 
     4270+endmenu 
     4271+ 
     4272+if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then 
     4273+   source drivers/char/pcmcia/Config.in 
     4274+fi 
     4275+if [ "$CONFIG_SOC_AU1X00" = "y" ]; then 
     4276+   tristate ' Alchemy Au1x00 GPIO device support' CONFIG_AU1X00_GPIO 
     4277+   tristate ' Au1000/ADS7846 touchscreen support' CONFIG_TS_AU1X00_ADS7846 
     4278+   #tristate ' Alchemy Au1550 PSC SPI support' CONFIG_AU1550_PSC_SPI 
     4279+fi 
     4280+if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then 
     4281+  tristate ' ITE GPIO' CONFIG_ITE_GPIO 
     4282+fi 
     4283+ 
     4284+if [ "$CONFIG_X86" = "y" ]; then 
     4285+   tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE 
     4286+   dep_tristate 'HP OB600 C/CT Pop-up mouse support' CONFIG_OBMOUSE $CONFIG_INPUT_MOUSEDEV 
     4287+fi 
     4288+ 
     4289+endmenu 
     4290diff -urN linux.old/drivers/char/Makefile linux.dev/drivers/char/Makefile 
     4291--- linux.old/drivers/char/Makefile     2005-10-21 16:43:16.460960500 +0200 
     4292+++ linux.dev/drivers/char/Makefile     2005-10-21 17:02:20.199991500 +0200 
     4293@@ -240,6 +240,13 @@ 
     4294 obj-y += joystick/js.o 
     4295 endif 
     4296  
     4297+# 
     4298+# Texas Intruments VLYNQ driver 
     4299+#  
     4300+ 
     4301+subdir-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq 
     4302+obj-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq/avalanche_vlynq.o                                                         
     4303+ 
     4304 obj-$(CONFIG_FETCHOP) += fetchop.o 
     4305 obj-$(CONFIG_BUSMOUSE) += busmouse.o 
     4306 obj-$(CONFIG_DTLK) += dtlk.o 
     4307@@ -340,6 +347,11 @@ 
     4308   obj-y += ipmi/ipmi.o 
     4309 endif 
     4310  
     4311+subdir-$(CONFIG_AR7_ADAM2) += ticfg 
     4312+ifeq ($(CONFIG_AR7_ADAM2),y) 
     4313+  obj-y += ticfg/ticfg.o 
     4314+endif 
     4315+ 
     4316 include $(TOPDIR)/Rules.make 
     4317  
     4318 fastdep: 
     4319diff -urN linux.old/drivers/char/Makefile.orig linux.dev/drivers/char/Makefile.orig 
     4320--- linux.old/drivers/char/Makefile.orig        1970-01-01 01:00:00.000000000 +0100 
     4321+++ linux.dev/drivers/char/Makefile.orig        2005-10-21 16:54:20.566016250 +0200 
     4322@@ -0,0 +1,374 @@ 
     4323+# 
     4324+# Makefile for the kernel character device drivers. 
     4325+# 
     4326+# Note! Dependencies are done automagically by 'make dep', which also 
     4327+# removes any old dependencies. DON'T put your own dependencies here 
     4328+# unless it's something special (ie not a .c file). 
     4329+# 
     4330+# Note 2! The CFLAGS definitions are now inherited from the 
     4331+# parent makes.. 
     4332+# 
     4333+ 
     4334+# 
     4335+# This file contains the font map for the default (hardware) font 
     4336+# 
     4337+FONTMAPFILE = cp437.uni 
     4338+ 
     4339+O_TARGET := char.o 
     4340+ 
     4341+obj-y   += mem.o tty_io.o n_tty.o tty_ioctl.o raw.o pty.o misc.o random.o 
     4342+ 
     4343+# All of the (potential) objects that export symbols. 
     4344+# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. 
     4345+ 
     4346+export-objs     :=     busmouse.o console.o keyboard.o sysrq.o \ 
     4347+                       misc.o pty.o random.o selection.o serial.o \ 
     4348+                       sonypi.o tty_io.o tty_ioctl.o generic_serial.o \ 
     4349+                       au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \ 
     4350+                       scx200.o fetchop.o 
     4351+ 
     4352+mod-subdirs    :=      joystick ftape drm drm-4.0 pcmcia 
     4353+ 
     4354+list-multi     :=       
     4355+ 
     4356+KEYMAP   =defkeymap.o 
     4357+KEYBD    =pc_keyb.o 
     4358+CONSOLE  =console.o 
     4359+SERIAL   =serial.o 
     4360+ 
     4361+ifeq ($(ARCH),s390) 
     4362+  KEYMAP   = 
     4363+  KEYBD    = 
     4364+  CONSOLE  = 
     4365+  SERIAL   = 
     4366+endif 
     4367+ 
     4368+ifeq ($(ARCH),mips) 
     4369+  ifneq ($(CONFIG_PC_KEYB),y) 
     4370+    KEYBD    = 
     4371+  endif 
     4372+  ifeq ($(CONFIG_VR41XX_KIU),y) 
     4373+    ifeq ($(CONFIG_IBM_WORKPAD),y) 
     4374+      KEYMAP = ibm_workpad_keymap.o 
     4375+    endif 
     4376+    ifeq ($(CONFIG_VICTOR_MPC30X),y) 
     4377+      KEYMAP = victor_mpc30x_keymap.o 
     4378+    endif 
     4379+    KEYBD    = vr41xx_keyb.o 
     4380+  endif 
     4381+endif 
     4382+ 
     4383+ifeq ($(ARCH),s390x) 
     4384+  KEYMAP   = 
     4385+  KEYBD    = 
     4386+  CONSOLE  = 
     4387+  SERIAL   = 
     4388+endif 
     4389+ 
     4390+ifeq ($(ARCH),m68k) 
     4391+   ifdef CONFIG_AMIGA 
     4392+      KEYBD = amikeyb.o 
     4393+   else 
     4394+      ifndef CONFIG_MAC 
     4395+        KEYBD = 
     4396+      endif 
     4397+   endif 
     4398+   SERIAL   = 
     4399+endif 
     4400+ 
     4401+ifeq ($(ARCH),parisc) 
     4402+   ifdef CONFIG_GSC_PS2 
     4403+      KEYBD   = hp_psaux.o hp_keyb.o 
     4404+   else 
     4405+      KEYBD   = 
     4406+   endif 
     4407+   ifdef CONFIG_SERIAL_MUX 
     4408+      CONSOLE += mux.o 
     4409+   endif 
     4410+   ifdef CONFIG_PDC_CONSOLE 
     4411+      CONSOLE += pdc_console.o 
     4412+   endif 
     4413+endif 
     4414+ 
     4415+ifdef CONFIG_Q40 
     4416+  KEYBD += q40_keyb.o 
     4417+  SERIAL = serial.o 
     4418+endif 
     4419+ 
     4420+ifdef CONFIG_APOLLO 
     4421+  KEYBD += dn_keyb.o 
     4422+endif 
     4423+ 
     4424+ifeq ($(ARCH),parisc) 
     4425+   ifdef CONFIG_GSC_PS2 
     4426+      KEYBD   = hp_psaux.o hp_keyb.o 
     4427+   else 
     4428+      KEYBD   = 
     4429+   endif 
     4430+   ifdef CONFIG_PDC_CONSOLE 
     4431+      CONSOLE += pdc_console.o 
     4432+   endif 
     4433+endif 
     4434+ 
     4435+ifeq ($(ARCH),arm) 
     4436+  ifneq ($(CONFIG_PC_KEYMAP),y) 
     4437+    KEYMAP   = 
     4438+  endif 
     4439+  ifneq ($(CONFIG_PC_KEYB),y) 
     4440+    KEYBD    = 
     4441+  endif 
     4442+endif 
     4443+ 
     4444+ifeq ($(ARCH),sh) 
     4445+  KEYMAP   = 
     4446+  KEYBD    = 
     4447+  CONSOLE  = 
     4448+  ifeq ($(CONFIG_SH_HP600),y) 
     4449+  KEYMAP   = defkeymap.o 
     4450+  KEYBD    = scan_keyb.o hp600_keyb.o 
     4451+  CONSOLE  = console.o 
     4452+  endif 
     4453+  ifeq ($(CONFIG_SH_DMIDA),y) 
     4454+  # DMIDA does not connect the HD64465 PS/2 keyboard port 
     4455+  # but we allow for USB keyboards to be plugged in. 
     4456+  KEYMAP   = defkeymap.o 
     4457+  KEYBD    = # hd64465_keyb.o pc_keyb.o 
     4458+  CONSOLE  = console.o 
     4459+  endif 
     4460+  ifeq ($(CONFIG_SH_EC3104),y) 
     4461+  KEYMAP   = defkeymap.o 
     4462+  KEYBD    = ec3104_keyb.o 
     4463+  CONSOLE  = console.o 
     4464+  endif 
     4465+  ifeq ($(CONFIG_SH_DREAMCAST),y) 
     4466+  KEYMAP   = defkeymap.o 
     4467+  KEYBD    = 
     4468+  CONSOLE  = console.o 
     4469+  endif 
     4470+endif 
     4471+ 
     4472+ifeq ($(CONFIG_DECSTATION),y) 
     4473+  KEYMAP   = 
     4474+  KEYBD    = 
     4475+endif 
     4476+ 
     4477+ifeq ($(CONFIG_BAGET_MIPS),y) 
     4478+  KEYBD    = 
     4479+  SERIAL   = vac-serial.o 
     4480+endif 
     4481+ 
     4482+ifeq ($(CONFIG_NINO),y) 
     4483+  SERIAL   = 
     4484+endif 
     4485+ 
     4486+ifneq ($(CONFIG_SUN_SERIAL),) 
     4487+  SERIAL   = 
     4488+endif 
     4489+ 
     4490+ifeq ($(CONFIG_QTRONIX_KEYBOARD),y) 
     4491+  KEYBD    = qtronix.o 
     4492+  KEYMAP   = qtronixmap.o 
     4493+endif 
     4494+ 
     4495+ifeq ($(CONFIG_DUMMY_KEYB),y) 
     4496+  KEYBD = dummy_keyb.o 
     4497+endif 
     4498+ 
     4499+obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o 
     4500+obj-$(CONFIG_SERIAL) += $(SERIAL) 
     4501+obj-$(CONFIG_PARPORT_SERIAL) += parport_serial.o 
     4502+obj-$(CONFIG_SERIAL_HCDP) += hcdp_serial.o 
     4503+obj-$(CONFIG_SERIAL_21285) += serial_21285.o 
     4504+obj-$(CONFIG_SERIAL_SA1100) += serial_sa1100.o 
     4505+obj-$(CONFIG_SERIAL_AMBA) += serial_amba.o 
     4506+obj-$(CONFIG_TS_AU1X00_ADS7846) += au1000_ts.o 
     4507+obj-$(CONFIG_SERIAL_DEC) += decserial.o 
     4508+ 
     4509+ifndef CONFIG_SUN_KEYBOARD 
     4510+  obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD) 
     4511+else 
     4512+  obj-$(CONFIG_PCI) += keyboard.o $(KEYMAP) 
     4513+endif 
     4514+ 
     4515+obj-$(CONFIG_HIL) += hp_keyb.o 
     4516+obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o 
     4517+obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o 
     4518+obj-$(CONFIG_ROCKETPORT) += rocket.o 
     4519+obj-$(CONFIG_MOXA_SMARTIO) += mxser.o 
     4520+obj-$(CONFIG_MOXA_INTELLIO) += moxa.o 
     4521+obj-$(CONFIG_DIGI) += pcxx.o 
     4522+obj-$(CONFIG_DIGIEPCA) += epca.o 
     4523+obj-$(CONFIG_CYCLADES) += cyclades.o 
     4524+obj-$(CONFIG_STALLION) += stallion.o 
     4525+obj-$(CONFIG_ISTALLION) += istallion.o 
     4526+obj-$(CONFIG_SIBYTE_SB1250_DUART) += sb1250_duart.o 
     4527+obj-$(CONFIG_COMPUTONE) += ip2.o ip2main.o 
     4528+obj-$(CONFIG_RISCOM8) += riscom8.o 
     4529+obj-$(CONFIG_ISI) += isicom.o 
     4530+obj-$(CONFIG_ESPSERIAL) += esp.o 
     4531+obj-$(CONFIG_SYNCLINK) += synclink.o 
     4532+obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o 
     4533+obj-$(CONFIG_N_HDLC) += n_hdlc.o 
     4534+obj-$(CONFIG_SPECIALIX) += specialix.o 
     4535+obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o 
     4536+obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o 
     4537+obj-$(CONFIG_SX) += sx.o generic_serial.o 
     4538+obj-$(CONFIG_RIO) += rio/rio.o generic_serial.o 
     4539+obj-$(CONFIG_SH_SCI) += sh-sci.o generic_serial.o 
     4540+obj-$(CONFIG_SERIAL167) += serial167.o 
     4541+obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o 
     4542+obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o 
     4543+obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o 
     4544+obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o 
     4545+obj-$(CONFIG_SERIAL_TX3912) += generic_serial.o serial_tx3912.o 
     4546+obj-$(CONFIG_TXX927_SERIAL) += serial_txx927.o 
     4547+obj-$(CONFIG_SERIAL_TXX9) += generic_serial.o serial_txx9.o 
     4548+obj-$(CONFIG_IP22_SERIAL) += sgiserial.o 
     4549+obj-$(CONFIG_AU1X00_UART) += au1x00-serial.o 
     4550+obj-$(CONFIG_SGI_L1_SERIAL) += sn_serial.o 
     4551+ 
     4552+subdir-$(CONFIG_RIO) += rio 
     4553+subdir-$(CONFIG_INPUT) += joystick 
     4554+ 
     4555+obj-$(CONFIG_ATIXL_BUSMOUSE) += atixlmouse.o 
     4556+obj-$(CONFIG_LOGIBUSMOUSE) += logibusmouse.o 
     4557+obj-$(CONFIG_PRINTER) += lp.o 
     4558+obj-$(CONFIG_TIPAR) += tipar.o 
     4559+obj-$(CONFIG_OBMOUSE) += obmouse.o 
     4560+ 
     4561+ifeq ($(CONFIG_INPUT),y) 
     4562+obj-y += joystick/js.o 
     4563+endif 
     4564+ 
     4565+# 
     4566+# Texas Intruments VLYNQ driver 
     4567+#  
     4568+ 
     4569+subdir-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq 
     4570+obj-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq/avalanche_vlynq.o                                                         
     4571+ 
     4572+obj-$(CONFIG_FETCHOP) += fetchop.o 
     4573+obj-$(CONFIG_BUSMOUSE) += busmouse.o 
     4574+obj-$(CONFIG_DTLK) += dtlk.o 
     4575+obj-$(CONFIG_R3964) += n_r3964.o 
     4576+obj-$(CONFIG_APPLICOM) += applicom.o 
     4577+obj-$(CONFIG_SONYPI) += sonypi.o 
     4578+obj-$(CONFIG_MS_BUSMOUSE) += msbusmouse.o 
     4579+obj-$(CONFIG_82C710_MOUSE) += qpmouse.o 
     4580+obj-$(CONFIG_AMIGAMOUSE) += amigamouse.o 
     4581+obj-$(CONFIG_ATARIMOUSE) += atarimouse.o 
     4582+obj-$(CONFIG_ADBMOUSE) += adbmouse.o 
     4583+obj-$(CONFIG_PC110_PAD) += pc110pad.o 
     4584+obj-$(CONFIG_MK712_MOUSE) += mk712.o 
     4585+obj-$(CONFIG_RTC) += rtc.o 
     4586+obj-$(CONFIG_GEN_RTC) += genrtc.o 
     4587+obj-$(CONFIG_EFI_RTC) += efirtc.o 
     4588+obj-$(CONFIG_MIPS_RTC) += mips_rtc.o 
     4589+obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o 
     4590+ifeq ($(CONFIG_PPC),) 
     4591+  obj-$(CONFIG_NVRAM) += nvram.o 
     4592+endif 
     4593+obj-$(CONFIG_TOSHIBA) += toshiba.o 
     4594+obj-$(CONFIG_I8K) += i8k.o 
     4595+obj-$(CONFIG_DS1286) += ds1286.o 
     4596+obj-$(CONFIG_DS1620) += ds1620.o 
     4597+obj-$(CONFIG_DS1742) += ds1742.o 
     4598+obj-$(CONFIG_INTEL_RNG) += i810_rng.o 
     4599+obj-$(CONFIG_AMD_RNG) += amd768_rng.o 
     4600+obj-$(CONFIG_HW_RANDOM) += hw_random.o 
     4601+obj-$(CONFIG_AMD_PM768) += amd76x_pm.o 
     4602+obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o 
     4603+ 
     4604+obj-$(CONFIG_ITE_GPIO) += ite_gpio.o 
     4605+obj-$(CONFIG_AU1X00_GPIO) += au1000_gpio.o 
     4606+obj-$(CONFIG_AU1550_PSC_SPI) += au1550_psc_spi.o 
     4607+obj-$(CONFIG_AU1X00_USB_TTY) += au1000_usbtty.o 
     4608+obj-$(CONFIG_AU1X00_USB_RAW) += au1000_usbraw.o 
     4609+obj-$(CONFIG_COBALT_LCD) += lcd.o 
     4610+ 
     4611+obj-$(CONFIG_QIC02_TAPE) += tpqic02.o 
     4612+ 
     4613+subdir-$(CONFIG_FTAPE) += ftape 
     4614+subdir-$(CONFIG_DRM_OLD) += drm-4.0 
     4615+subdir-$(CONFIG_DRM_NEW) += drm 
     4616+subdir-$(CONFIG_PCMCIA) += pcmcia 
     4617+subdir-$(CONFIG_AGP) += agp 
     4618+ 
     4619+ifeq ($(CONFIG_FTAPE),y) 
     4620+obj-y       += ftape/ftape.o 
     4621+endif 
     4622+ 
     4623+obj-$(CONFIG_H8) += h8.o 
     4624+obj-$(CONFIG_PPDEV) += ppdev.o 
     4625+obj-$(CONFIG_DZ) += dz.o 
     4626+obj-$(CONFIG_NWBUTTON) += nwbutton.o 
     4627+obj-$(CONFIG_NWFLASH) += nwflash.o 
     4628+obj-$(CONFIG_SCx200) += scx200.o 
     4629+obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o 
     4630+ 
     4631+# Only one watchdog can succeed. We probe the hardware watchdog 
     4632+# drivers first, then the softdog driver.  This means if your hardware 
     4633+# watchdog dies or is 'borrowed' for some reason the software watchdog 
     4634+# still gives you some cover. 
     4635+ 
     4636+obj-$(CONFIG_PCWATCHDOG) += pcwd.o 
     4637+obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o 
     4638+obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o 
     4639+obj-$(CONFIG_IB700_WDT) += ib700wdt.o 
     4640+obj-$(CONFIG_MIXCOMWD) += mixcomwd.o 
     4641+obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o 
     4642+obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o 
     4643+obj-$(CONFIG_SC520_WDT) += sc520_wdt.o 
     4644+obj-$(CONFIG_WDT) += wdt.o 
     4645+obj-$(CONFIG_WDTPCI) += wdt_pci.o 
     4646+obj-$(CONFIG_21285_WATCHDOG) += wdt285.o 
     4647+obj-$(CONFIG_977_WATCHDOG) += wdt977.o 
     4648+obj-$(CONFIG_I810_TCO) += i810-tco.o 
     4649+obj-$(CONFIG_MACHZ_WDT) += machzwd.o 
     4650+obj-$(CONFIG_SH_WDT) += shwdt.o 
     4651+obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o 
     4652+obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o 
     4653+obj-$(CONFIG_ALIM1535_WDT) += alim1535d_wdt.o 
     4654+obj-$(CONFIG_INDYDOG) += indydog.o 
     4655+obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o 
     4656+obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o 
     4657+obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o 
     4658+obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o 
     4659+obj-$(CONFIG_INDYDOG) += indydog.o 
     4660+obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o 
     4661+ 
     4662+subdir-$(CONFIG_MWAVE) += mwave 
     4663+ifeq ($(CONFIG_MWAVE),y) 
     4664+  obj-y += mwave/mwave.o 
     4665+endif 
     4666+ 
     4667+subdir-$(CONFIG_IPMI_HANDLER) += ipmi 
     4668+ifeq ($(CONFIG_IPMI_HANDLER),y) 
     4669+  obj-y += ipmi/ipmi.o 
     4670+endif 
     4671+ 
     4672+include $(TOPDIR)/Rules.make 
     4673+ 
     4674+fastdep: 
     4675+ 
     4676+conmakehash: conmakehash.c 
     4677+       $(HOSTCC) $(HOSTCFLAGS) -o conmakehash conmakehash.c 
     4678+ 
     4679+consolemap_deftbl.c: $(FONTMAPFILE) conmakehash 
     4680+       ./conmakehash $(FONTMAPFILE) > consolemap_deftbl.c 
     4681+ 
     4682+consolemap_deftbl.o: consolemap_deftbl.c $(TOPDIR)/include/linux/types.h 
     4683+ 
     4684+.DELETE_ON_ERROR: 
     4685+ 
     4686+defkeymap.c: defkeymap.map 
     4687+       set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ 
     4688+ 
     4689+qtronixmap.c: qtronixmap.map 
     4690+       set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ 
     4691+ 
     4692+ibm_workpad_keymap.c: ibm_workpad_keymap.map 
     4693+       set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ 
     4694+ 
     4695+victor_mpc30x_keymap.c: victor_mpc30x_keymap.map 
     4696+       set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ 
     4697diff -urN linux.old/drivers/char/avalanche_vlynq/Makefile linux.dev/drivers/char/avalanche_vlynq/Makefile 
     4698--- linux.old/drivers/char/avalanche_vlynq/Makefile     1970-01-01 01:00:00.000000000 +0100 
     4699+++ linux.dev/drivers/char/avalanche_vlynq/Makefile     2005-10-21 17:02:20.195991250 +0200 
     4700@@ -0,0 +1,16 @@ 
     4701+# 
     4702+# Makefile for the linux kernel. 
     4703+# 
     4704+# Note! Dependencies are done automagically by 'make dep', which also 
     4705+# removes any old dependencies. DON'T put your own dependencies here 
     4706+# unless it's something special (ie not a .c file). 
     4707+# 
     4708+# Note 2! The CFLAGS definitions are now in the main makefile... 
     4709+ 
     4710+O_TARGET := avalanche_vlynq.o 
     4711+ 
     4712+export-objs := vlynq_board.o 
     4713+ 
     4714+obj-y    +=  vlynq_drv.o  vlynq_hal.o  vlynq_board.o 
     4715+ 
     4716+include $(TOPDIR)/Rules.make 
     4717diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_board.c linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c 
     4718--- linux.old/drivers/char/avalanche_vlynq/vlynq_board.c        1970-01-01 01:00:00.000000000 +0100 
     4719+++ linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c        2005-10-21 17:02:20.195991250 +0200 
     4720@@ -0,0 +1,184 @@ 
     4721+/* 
     4722+ * Jeff Harrell, jharrell@ti.com 
     4723+ * Copyright (C) 2001 Texas Instruments, Inc.  All rights reserved. 
     4724+ * 
     4725+ *  This program is free software; you can distribute it and/or modify it 
     4726+ *  under the terms of the GNU General Public License (Version 2) as 
     4727+ *  published by the Free Software Foundation. 
     4728+ * 
     4729+ *  This program is distributed in the hope it will be useful, but WITHOUT 
     4730+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
     4731+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
     4732+ *  for more details. 
     4733+ * 
     4734+ *  You should have received a copy of the GNU General Public License along 
     4735+ *  with this program; if not, write to the Free Software Foundation, Inc., 
     4736+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 
     4737+ * 
     4738+ * Texas Instruments Sangam specific setup. 
     4739+ */ 
     4740+#include <linux/config.h> 
     4741+#include <linux/module.h> 
     4742+#include <asm/ar7/sangam.h>   
     4743+#include <asm/ar7/avalanche_misc.h>   
     4744+#include <asm/ar7/vlynq.h>   
     4745+    
     4746+#define SYS_VLYNQ_LOCAL_INTERRUPT_VECTOR       30      /* MSB - 1 bit */ 
     4747+#define SYS_VLYNQ_REMOTE_INTERRUPT_VECTOR      31      /* MSB bit */ 
     4748+#define SYS_VLYNQ_OPTIONS                      0x7F;   /* all options*/ 
     4749+ 
     4750+/* These defines are board specific */ 
     4751+ 
     4752+ 
     4753+#define VLYNQ0_REMOTE_WINDOW1_OFFSET           (0x0C000000) 
     4754+#define VLYNQ0_REMOTE_WINDOW1_SIZE             (0x500) 
     4755+ 
     4756+ 
     4757+#define VLYNQ1_REMOTE_WINDOW1_OFFSET           (0x0C000000) 
     4758+#define VLYNQ1_REMOTE_WINDOW1_SIZE             (0x500) 
     4759+ 
     4760+ 
     4761+extern VLYNQ_DEV vlynqDevice0, vlynqDevice1; 
     4762+int    vlynq_init_status[2] = {0, 0}; 
     4763+EXPORT_SYMBOL(vlynq_init_status); 
     4764+static int reset_hack = 1; 
     4765+ 
     4766+void vlynq_ar7wrd_dev_init() 
     4767+{ 
     4768+    *(unsigned long*) AVALANCHE_GPIO_ENBL    |= (1<<18); 
     4769+    vlynq_delay(20000); 
     4770+    *(unsigned long*) AVALANCHE_GPIO_DIR     &= ~(1<<18); 
     4771+    vlynq_delay(20000); 
     4772+    *(unsigned long*) AVALANCHE_GPIO_DATA_OUT&= ~(1<<18); 
     4773+    vlynq_delay(50000); 
     4774+    *(unsigned long*) AVALANCHE_GPIO_DATA_OUT|=  (1<<18); 
     4775+    vlynq_delay(50000); 
     4776+ 
     4777+    /* Initialize the MIPS host vlynq driver for a given vlynq interface */ 
     4778+    vlynqDevice0.dev_idx = 0;                  /* first vlynq module - this parameter is for reference only */ 
     4779+    vlynqDevice0.module_base = AVALANCHE_LOW_VLYNQ_CONTROL_BASE;       /*  vlynq0 module base address */ 
     4780+ 
     4781+#if defined(CONFIG_VLYNQ_CLK_LOCAL) 
     4782+    vlynqDevice0.clk_source = VLYNQ_CLK_SOURCE_LOCAL;    
     4783+#else 
     4784+    vlynqDevice0.clk_source = VLYNQ_CLK_SOURCE_REMOTE;    
     4785+#endif 
     4786+    vlynqDevice0.clk_div = 0x01;                       /* board/hardware specific */ 
     4787+    vlynqDevice0.state =  VLYNQ_DRV_STATE_UNINIT;      /* uninitialized module */ 
     4788+ 
     4789+    /* Populate vlynqDevice0.local_mem & Vlynq0.remote_mem based on system configuration */  
     4790+    /*Local memory configuration */ 
     4791+ 
     4792+                /* Demiurg : not good !*/ 
     4793+#if 0 
     4794+    vlynqDevice0.local_mem.Txmap= AVALANCHE_LOW_VLYNQ_MEM_MAP_BASE & ~(0xc0000000) ; /* physical address */ 
     4795+    vlynqDevice0.remote_mem.RxOffset[0]= VLYNQ0_REMOTE_WINDOW1_OFFSET; /* This is specific to the board on the other end */ 
     4796+    vlynqDevice0.remote_mem.RxSize[0]=VLYNQ0_REMOTE_WINDOW1_SIZE; 
     4797+#endif 
     4798+ 
     4799+                /* Demiurg : This is how it should be ! */ 
     4800+                vlynqDevice0.local_mem.Txmap = PHYSADDR(AVALANCHE_LOW_VLYNQ_MEM_MAP_BASE); 
     4801+#define VLYNQ_ACX111_MEM_OFFSET     0xC0000000  /* Physical address of ACX111 memory */ 
     4802+#define VLYNQ_ACX111_MEM_SIZE       0x00040000  /* Total size of the ACX111 memory   */ 
     4803+#define VLYNQ_ACX111_REG_OFFSET     0xF0000000  /* PHYS_ADDR of ACX111 control registers   */ 
     4804+#define VLYNQ_ACX111_REG_SIZE       0x00022000  /* Size of ACX111 registers area, MAC+PHY  */ 
     4805+#define ACX111_VL1_REMOTE_SIZE 0x1000000 
     4806+                vlynqDevice0.remote_mem.RxOffset[0]  =  VLYNQ_ACX111_MEM_OFFSET; 
     4807+                vlynqDevice0.remote_mem.RxSize[0]    =  VLYNQ_ACX111_MEM_SIZE  ; 
     4808+                vlynqDevice0.remote_mem.RxOffset[1]  =  VLYNQ_ACX111_REG_OFFSET; 
     4809+                vlynqDevice0.remote_mem.RxSize[1]    =  VLYNQ_ACX111_REG_SIZE  ; 
     4810+                vlynqDevice0.remote_mem.Txmap        =  0; 
     4811+                vlynqDevice0.local_mem.RxOffset[0]   =  AVALANCHE_SDRAM_BASE; 
     4812+                vlynqDevice0.local_mem.RxSize[0]     =  ACX111_VL1_REMOTE_SIZE; 
     4813+ 
     4814+ 
     4815+    /* Local interrupt configuration */ 
     4816+    vlynqDevice0.local_irq.intLocal = VLYNQ_INT_LOCAL;         /* Host handles vlynq interrupts*/ 
     4817+    vlynqDevice0.local_irq.intRemote = VLYNQ_INT_ROOT_ISR;     /* vlynq root isr used */ 
     4818+    vlynqDevice0.local_irq.map_vector = SYS_VLYNQ_LOCAL_INTERRUPT_VECTOR; 
     4819+    vlynqDevice0.local_irq.intr_ptr = 0; /* Since remote interrupts part of vlynq root isr this is unused */ 
     4820+ 
     4821+    /* Remote interrupt configuration */ 
     4822+    vlynqDevice0.remote_irq.intLocal = VLYNQ_INT_REMOTE;       /* MIPS handles interrupts */ 
     4823+    vlynqDevice0.remote_irq.intRemote = VLYNQ_INT_ROOT_ISR;    /* Not significant since MIPS handles interrupts */ 
     4824+    vlynqDevice0.remote_irq.map_vector = SYS_VLYNQ_REMOTE_INTERRUPT_VECTOR; 
     4825+    vlynqDevice0. remote_irq.intr_ptr = AVALANCHE_INTC_BASE; /* Not significant since MIPS handles interrupts */ 
     4826+ 
     4827+     if(reset_hack != 1) 
     4828+       printk("About to re-init the VLYNQ.\n"); 
     4829+ 
     4830+    if(vlynq_init(&vlynqDevice0,VLYNQ_INIT_PERFORM_ALL)== 0) 
     4831+    { 
     4832+        /* Suraj added the following to keep the 1130 going. */ 
     4833+        vlynq_interrupt_vector_set(&vlynqDevice0, 0 /* intr vector line running into 1130 vlynq */, 
     4834+                                   0 /* intr mapped onto the interrupt register on remote vlynq and this vlynq */, 
     4835+                                   VLYNQ_REMOTE_DVC, 0 /* polarity active high */, 0 /* interrupt Level triggered */); 
     4836+ 
     4837+        /* System wide interrupt is 80 for 1130, please note. */ 
     4838+        vlynq_init_status[0] = 1; 
     4839+        reset_hack = 2; 
     4840+    } 
     4841+    else 
     4842+    { 
     4843+        if(reset_hack == 1) 
     4844+            printk("VLYNQ INIT FAILED: Please try cold reboot. \n"); 
     4845+        else 
     4846+            printk("Failed to initialize the VLYNQ interface at insmod.\n"); 
     4847+ 
     4848+    } 
     4849+} 
     4850+ 
     4851+void  vlynq_dev_init(void) 
     4852+{ 
     4853+    volatile unsigned int *reset_base = (unsigned int *) AVALANCHE_RESET_CONTROL_BASE; 
     4854+ 
     4855+    *reset_base &= ~((1 << AVALANCHE_LOW_VLYNQ_RESET_BIT)); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT)); */ 
     4856+ 
     4857+    vlynq_delay(20000); 
     4858+ 
     4859+    /* Bring vlynq out of reset if not already done */ 
     4860+    *reset_base |= (1 << AVALANCHE_LOW_VLYNQ_RESET_BIT); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT); */ 
     4861+    vlynq_delay(20000); /* Allowing sufficient time to VLYNQ to settle down.*/ 
     4862+ 
     4863+    vlynq_ar7wrd_dev_init( ); 
     4864+ 
     4865+} 
     4866+ 
     4867+/* This function is board specific and should be ported for each board. */ 
     4868+void remote_vlynq_dev_reset_ctrl(unsigned int module_reset_bit, 
     4869+                                 AVALANCHE_RESET_CTRL_T reset_ctrl) 
     4870+{ 
     4871+    if(module_reset_bit >= 32) 
     4872+        return; 
     4873+ 
     4874+    switch(module_reset_bit) 
     4875+    { 
     4876+        case 0: 
     4877+            if(OUT_OF_RESET == reset_ctrl) 
     4878+            { 
     4879+                if(reset_hack) return; 
     4880+ 
     4881+                vlynq_delay(20000); 
     4882+                printk("Un-resetting the remote device.\n"); 
     4883+                vlynq_dev_init(); 
     4884+                printk("Re-initialized the VLYNQ.\n"); 
     4885+                reset_hack = 2; 
     4886+            } 
     4887+            else if(IN_RESET == reset_ctrl) 
     4888+            { 
     4889+                *(unsigned long*) AVALANCHE_GPIO_DATA_OUT &= ~(1<<18); 
     4890+ 
     4891+                vlynq_delay(20000); 
     4892+                printk("Resetting the remote device.\n"); 
     4893+                reset_hack = 0; 
     4894+            } 
     4895+            else 
     4896+                ; 
     4897+        break; 
     4898+ 
     4899+        default: 
     4900+        break; 
     4901+ 
     4902+    } 
     4903+} 
     4904+ 
     4905diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c 
     4906--- linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c  1970-01-01 01:00:00.000000000 +0100 
     4907+++ linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c  2005-10-21 17:02:20.199991500 +0200 
     4908@@ -0,0 +1,243 @@ 
     4909+/****************************************************************************** 
     4910+ * FILE PURPOSE:    Vlynq Linux Device Driver Source 
     4911+ ****************************************************************************** 
     4912+ * FILE NAME:       vlynq_drv.c 
     4913+ * 
     4914+ * DESCRIPTION:     Vlynq Linux Device Driver Source 
     4915+ * 
     4916+ * REVISION HISTORY: 
     4917+ * 
     4918+ * Date           Description                       Author 
     4919+ *----------------------------------------------------------------------------- 
     4920+ * 17 July 2003   Initial Creation                  Anant Gole 
     4921+ * 17 Dec  2003   Updates                           Sharath Kumar 
     4922+ * 
     4923+ * (C) Copyright 2003, Texas Instruments, Inc 
     4924+ *******************************************************************************/ 
     4925+  
     4926+#include <linux/config.h> 
     4927+#include <linux/init.h> 
     4928+#include <linux/module.h> 
     4929+#include <linux/sched.h> 
     4930+#include <linux/miscdevice.h> 
     4931+#include <linux/smp_lock.h> 
     4932+#include <linux/delay.h> 
     4933+#include <linux/proc_fs.h> 
     4934+#include <linux/capability.h> 
     4935+#include <asm/ar7/avalanche_intc.h> 
     4936+#include <asm/ar7/sangam.h> 
     4937+#include <asm/ar7/vlynq.h> 
     4938+ 
     4939+ 
     4940+#define    TI_VLYNQ_VERSION                 "0.2" 
     4941+ 
     4942+/* debug on ? */ 
     4943+#define VLYNQ_DEBUG  
     4944+ 
     4945+/* Macro for debug and error printf's */ 
     4946+#ifdef VLYNQ_DEBUG 
     4947+#define DBGPRINT  printk 
     4948+#else 
     4949+#define DBGPRINT(x)   
     4950+#endif 
     4951+ 
     4952+#define ERRPRINT  printk 
     4953+ 
     4954+/* Define the max vlynq ports this driver will support.  
     4955+   Device name strings are statically added here */ 
     4956+#define MAX_VLYNQ_PORTS 2 
     4957+ 
     4958+ 
     4959+/* Type define for VLYNQ private structure */ 
     4960+typedef struct vlynqPriv{ 
     4961+    int irq; 
     4962+    VLYNQ_DEV *vlynqDevice; 
     4963+}VLYNQ_PRIV; 
     4964+ 
     4965+extern int vlynq_init_status[2]; 
     4966+ 
     4967+/* Extern Global variable for vlynq devices used in initialization of the vlynq device 
     4968+ * These variables need to be populated/initialized by the system as part of initialization 
     4969+ * process. The vlynq enumerator can run at initialization and populate these globals 
     4970+ */ 
     4971+ 
     4972+VLYNQ_DEV vlynqDevice0; 
     4973+VLYNQ_DEV vlynqDevice1; 
     4974+ 
     4975+/* Defining dummy macro AVALANCHE_HIGH_VLYNQ_INT to take 
     4976+ * care of compilation in case of single vlynq device  
     4977+ */ 
     4978+ 
     4979+#ifndef AVALANCHE_HIGH_VLYNQ_INT 
     4980+#define  AVALANCHE_HIGH_VLYNQ_INT 0 
     4981+#endif 
     4982+ 
     4983+ 
     4984+ 
     4985+/* vlynq private object */ 
     4986+VLYNQ_PRIV vlynq_priv[CONFIG_AR7_VLYNQ_PORTS] = { 
     4987+    { LNXINTNUM(AVALANCHE_LOW_VLYNQ_INT),&vlynqDevice0}, 
     4988+    { LNXINTNUM(AVALANCHE_HIGH_VLYNQ_INT),&vlynqDevice1}, 
     4989+}; 
     4990+ 
     4991+extern void vlynq_dev_init(void); 
     4992+ 
     4993+ 
     4994+/* =================================== all the operations */ 
     4995+ 
     4996+static int 
     4997+vlynq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 
     4998+{ 
     4999+    return 0; 
     5000+} 
     5001+ 
     5002+static struct file_operations vlynq_fops = { 
     5003+    owner:      THIS_MODULE, 
     5004+    ioctl:      vlynq_ioctl, 
     5005+}; 
     5006+ 
     5007+/* Vlynq device object */ 
     5008+static struct miscdevice vlynq_dev [MAX_VLYNQ_PORTS] = { 
     5009+    { MISC_DYNAMIC_MINOR , "vlynq0", &vlynq_fops }, 
     5010+    { MISC_DYNAMIC_MINOR , "vlynq1", &vlynq_fops }, 
     5011+}; 
     5012+ 
     5013+ 
     5014+/* Proc read function */ 
     5015+static int 
     5016+vlynq_read_link_proc(char *buf, char **start, off_t offset, int count, int *eof, void *unused) 
     5017+{ 
     5018+    int instance; 
     5019+    int len = 0; 
     5020+  
     5021+    len += sprintf(buf +len,"VLYNQ Devices : %d\n",CONFIG_AR7_VLYNQ_PORTS); 
     5022+ 
     5023+    for(instance =0;instance < CONFIG_AR7_VLYNQ_PORTS;instance++) 
     5024+    { 
     5025+        int link_state; 
     5026+        char *link_msg[] = {" DOWN "," UP "}; 
     5027+        
     5028+        if(vlynq_init_status[instance] == 0) 
     5029+            link_state = 0;  
     5030+ 
     5031+        else if (vlynq_link_check(vlynq_priv[instance].vlynqDevice)) 
     5032+            link_state = 1; 
     5033+ 
     5034+        else 
     5035+            link_state = 0;     
     5036+ 
     5037+        len += sprintf(buf + len, "VLYNQ %d: Link state: %s\n",instance,link_msg[link_state]); 
     5038+ 
     5039+    } 
     5040+    /* Print info about vlynq device 1 */ 
     5041+    
     5042+    return len; 
     5043+} 
     5044+ 
     5045+ 
     5046+/* Proc function to display driver version */                                                                        
     5047+static int                                                                                      
     5048+vlynq_read_ver_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data)         
     5049+{                                                                                               
     5050+       int instance;                                                                               
     5051+       int len=0;                                                                                  
     5052+                                                                                                
     5053+       len += sprintf(buf +len,"\nTI Linux VLYNQ Driver Version %s\n",TI_VLYNQ_VERSION);          
     5054+       return len;                                                                                 
     5055+}                                                                                               
     5056+ 
     5057+ 
     5058+ 
     5059+ 
     5060+/* Wrapper for vlynq ISR */ 
     5061+static void lnx_vlynq_root_isr(int irq, void * arg, struct pt_regs *regs) 
     5062+{ 
     5063+   vlynq_root_isr(arg); 
     5064+} 
     5065+ 
     5066+/* =================================== init and cleanup */ 
     5067+ 
     5068+int vlynq_init_module(void) 
     5069+{ 
     5070+    int ret; 
     5071+    int unit = 0; 
     5072+    int instance_count = CONFIG_AR7_VLYNQ_PORTS; 
     5073+    volatile int *ptr; 
     5074+ 
     5075+    vlynq_dev_init(); 
     5076+ 
     5077+    DBGPRINT("Vlynq CONFIG_AR7_VLYNQ_PORTS=%d\n", CONFIG_AR7_VLYNQ_PORTS); 
     5078+    /* If num of configured vlynq ports > supported by driver return error */ 
     5079+    if (instance_count > MAX_VLYNQ_PORTS) 
     5080+    { 
     5081+        ERRPRINT("ERROR: vlynq_init_module(): Max %d supported\n", MAX_VLYNQ_PORTS); 
     5082+        return (-1); 
     5083+    } 
     5084+ 
     5085+    /* register the misc device */ 
     5086+    for (unit = 0; unit < CONFIG_AR7_VLYNQ_PORTS; unit++) 
     5087+    { 
     5088+        ret = misc_register(&vlynq_dev[unit]); 
     5089+ 
     5090+        if(ret < 0) 
     5091+        { 
     5092+            ERRPRINT("ERROR:Could not register vlynq device:%d\n",unit); 
     5093+            continue; 
     5094+        } 
     5095+        else  
     5096+            DBGPRINT("Vlynq Device %s registered with minor no %d as misc device. Result=%d\n",  
     5097+                vlynq_dev[unit].name, vlynq_dev[unit].minor, ret); 
     5098+#if 0 
     5099+             
     5100+        DBGPRINT("Calling vlynq init\n"); 
     5101+ 
     5102+        /* Read the global variable for VLYNQ device structure and initialize vlynq driver */ 
     5103+        ret = vlynq_init(vlynq_priv[unit].vlynqDevice,VLYNQ_INIT_PERFORM_ALL ); 
     5104+#endif 
     5105+ 
     5106+        if(vlynq_init_status[unit] == 0) 
     5107+        { 
     5108+            printk("VLYNQ %d : init failed\n",unit);  
     5109+            continue; 
     5110+        } 
     5111+          
     5112+        /* Check link before proceeding */ 
     5113+        if (!vlynq_link_check(vlynq_priv[unit].vlynqDevice)) 
     5114+        { 
     5115+           DBGPRINT("\nError: Vlynq link not available.trying once before  Exiting"); 
     5116+        } 
     5117+        else 
     5118+        { 
     5119+            DBGPRINT("Vlynq instance:%d Link UP\n",unit); 
     5120+         
     5121+            /* Install the vlynq local root ISR */ 
     5122+           request_irq(vlynq_priv[unit].irq,lnx_vlynq_root_isr,0,vlynq_dev[unit].name,vlynq_priv[unit].vlynqDevice); 
     5123+        }  
     5124+    } 
     5125+ 
     5126+    proc_mkdir("avalanche", NULL); 
     5127+    /* Creating proc entry for the devices */ 
     5128+    create_proc_read_entry("avalanche/vlynq_link", 0, NULL, vlynq_read_link_proc, NULL); 
     5129+    create_proc_read_entry("avalanche/vlynq_ver", 0, NULL, vlynq_read_ver_proc, NULL); 
     5130 
     5131+    return 0; 
     5132+} 
     5133+ 
     5134+void vlynq_cleanup_module(void) 
     5135+{ 
     5136+    int unit = 0; 
     5137+     
     5138+    for (unit = 0; unit < CONFIG_AR7_VLYNQ_PORTS; unit++) 
     5139+    { 
     5140+        DBGPRINT("vlynq_cleanup_module(): Unregistring misc device %s\n",vlynq_dev[unit].name); 
     5141+        misc_deregister(&vlynq_dev[unit]); 
     5142+    } 
     5143+ 
     5144+    remove_proc_entry("avalanche/vlynq_link", NULL); 
     5145+    remove_proc_entry("avalanche/vlynq_ver", NULL); 
     5146+} 
     5147+ 
     5148+ 
     5149+module_init(vlynq_init_module); 
     5150+module_exit(vlynq_cleanup_module); 
     5151+ 
     5152diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c 
     5153--- linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c  1970-01-01 01:00:00.000000000 +0100 
     5154+++ linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c  2005-10-21 16:45:47.838421000 +0200 
     5155@@ -0,0 +1,1214 @@ 
     5156+/*************************************************************************** 
     5157+**+----------------------------------------------------------------------+** 
     5158+**|                                ****                                  |** 
     5159+**|                                ****                                  |** 
     5160+**|                                ******o***                            |** 
     5161+**|                          ********_///_****                           |** 
     5162+**|                           ***** /_//_/ ****                          |** 
     5163+**|                            ** ** (__/ ****                           |** 
     5164+**|                                *********                             |** 
     5165+**|                                 ****                                 |** 
     5166+**|                                  ***                                 |** 
     5167+**|                                                                      |** 
     5168+**|     Copyright (c) 2003 Texas Instruments Incorporated                |** 
     5169+**|                        ALL RIGHTS RESERVED                           |** 
     5170+**|                                                                      |** 
     5171+**| Permission is hereby granted to licensees of Texas Instruments       |** 
     5172+**| Incorporated (TI) products to use this computer program for the sole |** 
     5173+**| purpose of implementing a licensee product based on TI products.     |** 
     5174+**| No other rights to reproduce, use, or disseminate this computer      |** 
     5175+**| program, whether in part or in whole, are granted.                   |** 
     5176+**|                                                                      |** 
     5177+**| TI makes no representation or warranties with respect to the         |** 
     5178+**| performance of this computer program, and specifically disclaims     |** 
     5179+**| any responsibility for any damages, special or consequential,        |** 
     5180+**| connected with the use of this program.                              |** 
     5181+**|                                                                      |** 
     5182+**+----------------------------------------------------------------------+** 
     5183+***************************************************************************/ 
     5184+ 
     5185+/*************************************************************************** 
     5186+ *  ------------------------------------------------------------------------------ 
     5187+ *   Module      : vlynq_hal.c 
     5188+ *   Description : This file implements VLYNQ HAL API. 
     5189+ *  ------------------------------------------------------------------------------ 
     5190+ ***************************************************************************/ 
     5191+ 
     5192+#include <linux/stddef.h> 
     5193+#include <linux/types.h> 
     5194+#include <asm/ar7/vlynq.h> 
     5195+ 
     5196+/**** Local Function prototypes *******/ 
     5197+static int vlynqInterruptInit(VLYNQ_DEV *pdev); 
     5198+static void  vlynq_configClock(VLYNQ_DEV  *pdev); 
     5199+ 
     5200+/*** Second argument must be explicitly type casted to  
     5201+ * (VLYNQ_DEV*) inside the following functions */ 
     5202+static void vlynq_local_module_isr(void *arg1, void *arg2, void *arg3); 
     5203+static void vlynq_remote_module_isr(void *arg1, void *arg2, void *arg3); 
     5204+ 
     5205+ 
     5206+volatile int vlynq_delay_value = 0; 
     5207+ 
     5208+/* Code adopted from original vlynq driver */ 
     5209+void vlynq_delay(unsigned int clktime) 
     5210+{ 
     5211+    int i = 0; 
     5212+    volatile int    *ptr = &vlynq_delay_value; 
     5213+    *ptr = 0; 
     5214+ 
     5215+    /* We are assuming that the each cycle takes about  
     5216+     * 23 assembly instructions. */ 
     5217+    for(i = 0; i < (clktime + 23)/23; i++) 
     5218+    { 
     5219+        *ptr = *ptr + 1; 
     5220+    } 
     5221+} 
     5222+ 
     5223+ 
     5224+/* ---------------------------------------------------------------------------- 
     5225+ *  Function : vlynq_configClock() 
     5226+ *  Description: Configures clock settings based on input parameters 
     5227+ *  Adapted from original vlyna driver from Cable 
     5228+ */ 
     5229+static void vlynq_configClock(VLYNQ_DEV * pdev) 
     5230+{ 
     5231+    unsigned int tmp; 
     5232+ 
     5233+    switch( pdev->clk_source) 
     5234+    { 
     5235+        case VLYNQ_CLK_SOURCE_LOCAL:  /* we output the clock, clk_div in range [1..8]. */ 
     5236+            tmp = ((pdev->clk_div - 1) << 16) |  VLYNQ_CTL_CLKDIR_MASK ; 
     5237+            VLYNQ_CTRL_REG = tmp; 
     5238+            VLYNQ_R_CTRL_REG = 0ul; 
     5239+            break; 
     5240+        case VLYNQ_CLK_SOURCE_REMOTE: /* we need to set the clock pin as input */ 
     5241+            VLYNQ_CTRL_REG = 0ul; 
     5242+            tmp = ((pdev->clk_div - 1) << 16) |  VLYNQ_CTL_CLKDIR_MASK ; 
     5243+            VLYNQ_R_CTRL_REG = tmp; 
     5244+            break; 
     5245+        default:   /* do nothing about the clock, but clear other bits. */ 
     5246+            tmp = ~(VLYNQ_CTL_CLKDIR_MASK | VLYNQ_CTL_CLKDIV_MASK); 
     5247+            VLYNQ_CTRL_REG &= tmp; 
     5248+            break; 
     5249+   } 
     5250+} 
     5251+ 
     5252+ /* ---------------------------------------------------------------------------- 
     5253+ *  Function : vlynq_link_check() 
     5254+ *  Description: This function checks the current VLYNQ for a link. 
     5255+ *  An arbitrary amount of time is allowed for the link to come up . 
     5256+ *  Returns 0 for "no link / failure " and 1 for "link available". 
     5257+ * ----------------------------------------------------------------------------- 
     5258+ */ 
     5259+unsigned int vlynq_link_check( VLYNQ_DEV * pdev) 
     5260+{ 
     5261+    /*sleep for 64 cycles, allow link to come up*/ 
     5262+    vlynq_delay(64);   
     5263+       
     5264+    /* check status register return OK if link is found. */ 
     5265+    if (VLYNQ_STATUS_REG & VLYNQ_STS_LINK_MASK)  
     5266+    { 
     5267+        return 1;   /* Link Available */ 
     5268+    } 
     5269+    else 
     5270+    { 
     5271+        return 0;   /* Link Failure */ 
     5272+    } 
     5273+} 
     5274+ 
     5275+/* ---------------------------------------------------------------------------- 
     5276+ *  Function : vlynq_init() 
     5277+ *  Description: Initialization function accepting paramaters for VLYNQ module 
     5278+ *  initialization. The Options bitmap decides what operations are performed 
     5279+ *  as a part of initialization. The Input parameters  are obtained through the 
     5280+ *  sub fields of VLYNQ_DEV structure. 
     5281+ */ 
     5282+ 
     5283+int vlynq_init(VLYNQ_DEV *pdev, VLYNQ_INIT_OPTIONS options) 
     5284+{ 
     5285+    unsigned int map; 
     5286+    unsigned int val=0,cnt,tmp; 
     5287+    unsigned int counter=0; 
     5288+    VLYNQ_INTERRUPT_CNTRL *intSetting=NULL; 
     5289+ 
     5290+    /* validate arguments */ 
     5291+    if( VLYNQ_OUTRANGE(pdev->clk_source, VLYNQ_CLK_SOURCE_REMOTE, VLYNQ_CLK_SOURCE_NONE) ||  
     5292+        VLYNQ_OUTRANGE(pdev->clk_div, 8, 1) ) 
     5293+    { 
     5294+      return VLYNQ_INVALID_ARG; 
     5295+    } 
     5296+    
     5297+    /** perform all sanity checks first **/ 
     5298+    if(pdev->state != VLYNQ_DRV_STATE_UNINIT) 
     5299+        return VLYNQ_INVALID_DRV_STATE; 
     5300+ 
     5301+    /** Initialize local and remote register set addresses- additional 
     5302+     * provision to access the registers directly if need be */ 
     5303+    pdev->local = (VLYNQ_REG_SET*)pdev->module_base; 
     5304+    pdev->remote = (VLYNQ_REG_SET*) (pdev->module_base + VLYNQ_REMOTE_REGS_OFFSET); 
     5305+ 
     5306+    /* Detect faulty int configuration that might induce int pkt looping */ 
     5307+    if ( (options  & VLYNQ_INIT_LOCAL_INTERRUPTS) && (options & VLYNQ_INIT_REMOTE_INTERRUPTS) ) 
     5308+    { 
     5309+        /* case when both local and remote are configured */ 
     5310+        if((pdev->local_irq.intLocal== VLYNQ_INT_REMOTE )  /* interrupts transfered to remote from local */ 
     5311+        && (pdev->remote_irq.intLocal== VLYNQ_INT_REMOTE)  /* interrupts transfered from remote to local */ 
     5312+        && ((pdev->local_irq.intRemote == VLYNQ_INT_ROOT_ISR) || (pdev->remote_irq.intRemote == VLYNQ_INT_ROOT_ISR)) ) 
     5313+        { 
     5314+            return (VLYNQ_INT_CONFIG_ERR);  
     5315+        } 
     5316+    } 
     5317+ 
     5318+    pdev->state = VLYNQ_DRV_STATE_ININIT; 
     5319+    pdev->intCount = 0; 
     5320+    pdev->isrCount = 0; 
     5321+ 
     5322+    /*** Its assumed that the vlynq module  has been brought out of reset 
     5323+     * before invocation of vlynq_init. Since, this operation is board specific 
     5324+     * it must be handled outside this generic driver */ 
     5325+    
     5326+    /* Assert reset the remote device, call reset_cb, 
     5327+     * reset CB holds Reset according to the device needs. */ 
     5328+    VLYNQ_RESETCB(VLYNQ_RESET_ASSERT); 
     5329+ 
     5330+    /* Handle VLYNQ clock, HW default (Sense On Reset) is 
     5331+     * usually input for all the devices. */         
     5332+    if (options & VLYNQ_INIT_CONFIG_CLOCK) 
     5333+    { 
     5334+        vlynq_configClock(pdev); 
     5335+    } 
     5336+  
     5337+    /* Call reset_cb again. It will release the remote device  
     5338+     * from reset, and wait for a while. */ 
     5339+    VLYNQ_RESETCB(VLYNQ_RESET_DEASSERT); 
     5340+ 
     5341+    if(options & VLYNQ_INIT_CHECK_LINK ) 
     5342+    { 
     5343+        /* Check for link up during initialization*/ 
     5344+       while( counter < 25 ) 
     5345+       { 
     5346+       /* loop around giving a chance for link status to settle down */ 
     5347+       counter++; 
     5348+        if(vlynq_link_check(pdev)) 
     5349+        { 
     5350+           /* Link is up exit loop*/ 
     5351+          break; 
     5352+        } 
     5353+ 
     5354+       vlynq_delay(4000); 
     5355+       }/*end of while counter loop */ 
     5356+ 
     5357+        if(!vlynq_link_check(pdev)) 
     5358+        { 
     5359+            /* Handle this case as abort */ 
     5360+            pdev->state = VLYNQ_DRV_STATE_ERROR; 
     5361+            VLYNQ_RESETCB( VLYNQ_RESET_INITFAIL); 
     5362+            return VLYNQ_LINK_DOWN; 
     5363+        }/* end of if not vlynq_link_check conditional block */ 
     5364+       
     5365+    }/*end of if options & VLYNQ_INIT_CHECK_LINK conditional block */ 
     5366+ 
     5367+ 
     5368+    if (options & VLYNQ_INIT_LOCAL_MEM_REGIONS) 
     5369+    { 
     5370+        /* Initialise local memory regions . This initialization lets 
     5371+         * the local host access remote device memory regions*/    
     5372+        int i;  
     5373+ 
     5374+        /* configure the VLYNQ portal window to a PHYSICAL 
     5375+         * address of the local CPU */ 
     5376+        VLYNQ_ALIGN4(pdev->local_mem.Txmap); 
     5377+        VLYNQ_TXMAP_REG = (pdev->local_mem.Txmap);  
     5378+         
     5379+        /*This code assumes input parameter is itself a physical address */ 
     5380+        for(i=0; i < VLYNQ_MAX_MEMORY_REGIONS ; i++) 
     5381+        { 
     5382+            /* Physical address on the remote */ 
     5383+            map = i+1; 
     5384+            VLYNQ_R_RXMAP_SIZE_REG(map) =  0; 
     5385+            if( pdev->remote_mem.RxSize[i]) 
     5386+            { 
     5387+                VLYNQ_ALIGN4(pdev->remote_mem.RxOffset[i]);             
     5388+                VLYNQ_ALIGN4(pdev->remote_mem.RxSize[i]); 
     5389+                VLYNQ_R_RXMAP_OFFSET_REG(map) = pdev->remote_mem.RxOffset[i]; 
     5390+                VLYNQ_R_RXMAP_SIZE_REG(map) = pdev->remote_mem.RxSize[i]; 
     5391+            } 
     5392+        } 
     5393+    } 
     5394+ 
     5395+    if(options & VLYNQ_INIT_REMOTE_MEM_REGIONS ) 
     5396+    { 
     5397+        int i; 
     5398+ 
     5399+        /* Initialise remote memory regions. This initialization lets remote 
     5400+         * device access local host memory regions. It configures the VLYNQ portal 
     5401+         * window to a PHYSICAL address of the remote */ 
     5402+        VLYNQ_ALIGN4(pdev->remote_mem.Txmap);             
     5403+        VLYNQ_R_TXMAP_REG = pdev->remote_mem.Txmap; 
     5404+        
     5405+        for( i=0; i<VLYNQ_MAX_MEMORY_REGIONS; i++) 
     5406+        { 
     5407+            /* Physical address on the local */ 
     5408+            map = i+1; 
     5409+            VLYNQ_RXMAP_SIZE_REG(map) =  0; 
     5410+            if( pdev->local_mem.RxSize[i]) 
     5411+            { 
     5412+                VLYNQ_ALIGN4(pdev->local_mem.RxOffset[i]);             
     5413+                VLYNQ_ALIGN4(pdev->local_mem.RxSize[i]); 
     5414+                VLYNQ_RXMAP_OFFSET_REG(map) =  (pdev->local_mem.RxOffset[i]); 
     5415+                VLYNQ_RXMAP_SIZE_REG(map) =  (pdev->local_mem.RxSize[i]); 
     5416+            } 
     5417+        } 
     5418+    } 
     5419+ 
     5420+    /* Adapted from original vlynq driver from cable - Calculate VLYNQ bus width */ 
     5421+    pdev->width = 3 +  VLYNQ_STATUS_FLD_WIDTH(VLYNQ_STATUS_REG)  
     5422+                  + VLYNQ_STATUS_FLD_WIDTH(VLYNQ_R_STATUS_REG); 
     5423+    
     5424+    /* chance to initialize the device, e.g. to boost VLYNQ  
     5425+     * clock by modifying pdev->clk_div or and verify the width. */ 
     5426+    VLYNQ_RESETCB(VLYNQ_RESET_LINKESTABLISH); 
     5427+ 
     5428+    /* Handle VLYNQ clock, HW default (Sense On Reset) is 
     5429+     * usually input for all the devices. */ 
     5430+    if(options & VLYNQ_INIT_CONFIG_CLOCK ) 
     5431+    { 
     5432+        vlynq_configClock(pdev); 
     5433+    } 
     5434+ 
     5435+    /* last check for link*/ 
     5436+    if(options & VLYNQ_INIT_CHECK_LINK ) 
     5437+    { 
     5438+     /* Final Check for link during initialization*/ 
     5439+       while( counter < 25 ) 
     5440+       { 
     5441+       /* loop around giving a chance for link status to settle down */ 
     5442+       counter++; 
     5443+        if(vlynq_link_check(pdev)) 
     5444+        { 
     5445+           /* Link is up exit loop*/ 
     5446+          break; 
     5447+        } 
     5448+ 
     5449+       vlynq_delay(4000); 
     5450+       }/*end of while counter loop */ 
     5451+ 
     5452+        if(!vlynq_link_check(pdev)) 
     5453+        { 
     5454+            /* Handle this case as abort */ 
     5455+            pdev->state = VLYNQ_DRV_STATE_ERROR; 
     5456+            VLYNQ_RESETCB( VLYNQ_RESET_INITFAIL); 
     5457+            return VLYNQ_LINK_DOWN; 
     5458+        }/* end of if not vlynq_link_check conditional block */ 
     5459+         
     5460+    } /* end of if options & VLYNQ_INIT_CHECK_LINK */ 
     5461+ 
     5462+    if(options & VLYNQ_INIT_LOCAL_INTERRUPTS ) 
     5463+    { 
     5464+        /* Configure local interrupt settings */ 
     5465+        intSetting = &(pdev->local_irq); 
     5466+ 
     5467+        /* Map local module status interrupts to interrupt vector*/ 
     5468+        val = intSetting->map_vector << VLYNQ_CTL_INTVEC_SHIFT ; 
     5469+       
     5470+        /* enable local module status interrupts */ 
     5471+        val |= 0x01 << VLYNQ_CTL_INTEN_SHIFT; 
     5472+       
     5473+        if ( intSetting->intLocal == VLYNQ_INT_LOCAL ) 
     5474+        { 
     5475+            /*set the intLocal bit*/ 
     5476+            val |= 0x01 << VLYNQ_CTL_INTLOCAL_SHIFT; 
     5477+        } 
     5478+       
     5479+        /* Irrespective of whether interrupts are handled locally, program 
     5480+         * int2Cfg. Error checking for accidental loop(when intLocal=0 and int2Cfg=1 
     5481+         * i.e remote packets are set intPending register->which will result in  
     5482+         * same packet being sent out) has been done already 
     5483+         */ 
     5484+       
     5485+        if (intSetting->intRemote == VLYNQ_INT_ROOT_ISR)  
     5486+        { 
     5487+            /* Set the int2Cfg register, so that remote interrupt 
     5488+             * packets are written to intPending register */ 
     5489+            val |= 0x01 << VLYNQ_CTL_INT2CFG_SHIFT; 
     5490+     
     5491+            /* Set intPtr register to point to intPending register */ 
     5492+            VLYNQ_INT_PTR_REG = VLYNQ_INT_PENDING_REG_PTR ; 
     5493+        } 
     5494+        else 
     5495+        { 
     5496+            /*set the interrupt pointer register*/ 
     5497+            VLYNQ_INT_PTR_REG = intSetting->intr_ptr; 
     5498+            /* Dont bother to modify int2Cfg as it would be zero */ 
     5499+        } 
     5500+ 
     5501+        /** Clear bits related to INT settings in control register **/ 
     5502+        VLYNQ_CTRL_REG = VLYNQ_CTRL_REG & (~VLYNQ_CTL_INTFIELDS_CLEAR_MASK); 
     5503+       
     5504+        /** Or the bits to be set with Control register **/ 
     5505+        VLYNQ_CTRL_REG = VLYNQ_CTRL_REG | val; 
     5506+ 
     5507+        /* initialise local ICB */           
     5508+        if(vlynqInterruptInit(pdev)==VLYNQ_MEMALLOC_FAIL) 
     5509+            return VLYNQ_MEMALLOC_FAIL;    
     5510+ 
     5511+        /* Install handler for local module status interrupts. By default when  
     5512+         * local interrupt setting is initialised, the local module status are  
     5513+         * enabled and handler hooked up */ 
     5514+        if(vlynq_install_isr(pdev, intSetting->map_vector, vlynq_local_module_isr,  
     5515+                             pdev, NULL, NULL) == VLYNQ_INVALID_ARG) 
     5516+            return VLYNQ_INVALID_ARG; 
     5517+    } /* end of init local interrupts */ 
     5518+ 
     5519+    if(options & VLYNQ_INIT_REMOTE_INTERRUPTS ) 
     5520+    { 
     5521+        /* Configure remote interrupt settings from configuration */           
     5522+        intSetting = &(pdev->remote_irq); 
     5523+ 
     5524+        /* Map remote module status interrupts to remote interrupt vector*/ 
     5525+        val = intSetting->map_vector << VLYNQ_CTL_INTVEC_SHIFT ; 
     5526+        /* enable remote module status interrupts */ 
     5527+        val |= 0x01 << VLYNQ_CTL_INTEN_SHIFT; 
     5528+       
     5529+        if ( intSetting->intLocal == VLYNQ_INT_LOCAL ) 
     5530+        { 
     5531+            /*set the intLocal bit*/ 
     5532+            val |= 0x01 << VLYNQ_CTL_INTLOCAL_SHIFT; 
     5533+        } 
     5534+ 
     5535+        /* Irrespective of whether interrupts are handled locally, program 
     5536+         * int2Cfg. Error checking for accidental loop(when intLocal=0 and int2Cfg=1 
     5537+         * i.e remote packets are set intPending register->which will result in  
     5538+         * same packet being sent out) has been done already 
     5539+        */  
     5540+ 
     5541+        if (intSetting->intRemote == VLYNQ_INT_ROOT_ISR)  
     5542+        { 
     5543+            /* Set the int2Cfg register, so that remote interrupt 
     5544+             * packets are written to intPending register */ 
     5545+            val |= 0x01 << VLYNQ_CTL_INT2CFG_SHIFT; 
     5546+            /* Set intPtr register to point to intPending register */ 
     5547+            VLYNQ_R_INT_PTR_REG = VLYNQ_R_INT_PENDING_REG_PTR ; 
     5548+        } 
     5549+        else 
     5550+        { 
     5551+            /*set the interrupt pointer register*/ 
     5552+            VLYNQ_R_INT_PTR_REG = intSetting->intr_ptr; 
     5553+            /* Dont bother to modify int2Cfg as it would be zero */ 
     5554+        } 
     5555+     
     5556+        if( (intSetting->intLocal == VLYNQ_INT_REMOTE) &&  
     5557+            (options & VLYNQ_INIT_LOCAL_INTERRUPTS) && 
     5558+            (pdev->local_irq.intRemote == VLYNQ_INT_ROOT_ISR) ) 
     5559+        { 
     5560+            /* Install handler for remote module status interrupts. By default when  
     5561+             * remote interrupts are forwarded to local root_isr then remote_module_isr is 
     5562+             * enabled and handler hooked up */ 
     5563+            if(vlynq_install_isr(pdev,intSetting->map_vector,vlynq_remote_module_isr, 
     5564+                                 pdev, NULL, NULL) == VLYNQ_INVALID_ARG) 
     5565+                return VLYNQ_INVALID_ARG; 
     5566+        } 
     5567+ 
     5568+          
     5569+        /** Clear bits related to INT settings in control register **/ 
     5570+        VLYNQ_R_CTRL_REG = VLYNQ_R_CTRL_REG & (~VLYNQ_CTL_INTFIELDS_CLEAR_MASK); 
     5571+       
     5572+        /** Or the bits to be set with the remote Control register **/ 
     5573+        VLYNQ_R_CTRL_REG = VLYNQ_R_CTRL_REG | val; 
     5574+          
     5575+    } /* init remote interrupt settings*/ 
     5576+ 
     5577+    if(options & VLYNQ_INIT_CLEAR_ERRORS ) 
     5578+    { 
     5579+        /* Clear errors during initialization */ 
     5580+        tmp = VLYNQ_STATUS_REG  & (VLYNQ_STS_RERROR_MASK | VLYNQ_STS_LERROR_MASK); 
     5581+        VLYNQ_STATUS_REG = tmp; 
     5582+        tmp = VLYNQ_R_STATUS_REG & (VLYNQ_STS_RERROR_MASK | VLYNQ_STS_LERROR_MASK); 
     5583+        VLYNQ_R_STATUS_REG = tmp; 
     5584+    }  
     5585+ 
     5586+    /* clear int status */ 
     5587+    val = VLYNQ_INT_STAT_REG; 
     5588+    VLYNQ_INT_STAT_REG = val; 
     5589+     
     5590+    /* finish initialization */ 
     5591+    pdev->state = VLYNQ_DRV_STATE_RUN; 
     5592+    VLYNQ_RESETCB( VLYNQ_RESET_INITOK); 
     5593+    return VLYNQ_SUCCESS; 
     5594+ 
     5595+} 
     5596+ 
     5597+ 
     5598+/* ---------------------------------------------------------------------------- 
     5599+ *  Function : vlynqInterruptInit() 
     5600+ *  Description: This local function is used to set up the ICB table for the  
     5601+ *  VLYNQ_STATUS_REG vlynq module. The input parameter "pdev" points the vlynq 
     5602+ *  device instance whose ICB is allocated. 
     5603+ *  Return : returns VLYNQ_SUCCESS or vlynq error for failure 
     5604+ * ----------------------------------------------------------------------------- 
     5605+ */ 
     5606+static int vlynqInterruptInit(VLYNQ_DEV *pdev) 
     5607+{ 
     5608+    int i, numslots; 
     5609+ 
     5610+    /* Memory allocated statically. 
     5611+     * Initialise ICB,free list.Indicate primary slot empty. 
     5612+     * Intialise intVector <==> map_vector translation table*/ 
     5613+    for(i=0; i < VLYNQ_NUM_INT_BITS; i++) 
     5614+    { 
     5615+        pdev->pIntrCB[i].isr = NULL;   
     5616+        pdev->pIntrCB[i].next = NULL; /*nothing chained */ 
     5617+        pdev->vector_map[i] = -1;   /* indicates unmapped  */ 
     5618+    } 
     5619+ 
     5620+    /* In the ICB slots, [VLYNQ_NUM_INT_BITS i.e 32 to ICB array size) are expansion slots 
     5621+     * required only when interrupt chaining/sharing is supported. In case 
     5622+     * of chained interrupts the list starts from primary slot and the 
     5623+     * additional slots are obtained from the common free area */ 
     5624+ 
     5625+    /* Initialise freelist */ 
     5626+ 
     5627+    numslots = VLYNQ_NUM_INT_BITS + VLYNQ_IVR_CHAIN_SLOTS; 
     5628+     
     5629+    if (numslots > VLYNQ_NUM_INT_BITS) 
     5630+    { 
     5631+        pdev->freelist = &(pdev->pIntrCB[VLYNQ_NUM_INT_BITS]); 
     5632+         
     5633+        for(i = VLYNQ_NUM_INT_BITS; i < (numslots-1) ; i++) 
     5634+        { 
     5635+            pdev->pIntrCB[i].next = &(pdev->pIntrCB[i+1]); 
     5636+            pdev->pIntrCB[i].isr = NULL; 
     5637+        } 
     5638+        pdev->pIntrCB[i].next=NULL; /* Indicate end of freelist*/ 
     5639+        pdev->pIntrCB[i].isr=NULL; 
     5640+    }   
     5641+    else 
     5642+    {    
     5643+        pdev->freelist = NULL; 
     5644+    } 
     5645+ 
     5646+    /** Reset mapping for IV 0-7 **/ 
     5647+    VLYNQ_IVR_03TO00_REG = 0; 
     5648+    VLYNQ_IVR_07TO04_REG = 0; 
     5649+ 
     5650+    return VLYNQ_SUCCESS; 
     5651+} 
     5652+ 
     5653+/** remember that hooking up of root ISR handler with the interrupt controller  
     5654+ *  is not done as a part of this driver. Typically, it must be done after 
     5655+ *  invoking vlynq_init*/ 
     5656+ 
     5657+ 
     5658+ /* ---------------------------------------------------------------------------- 
     5659+ *  ISR with the SOC interrupt controller. This ISR typically scans 
     5660+ *  the Int PENDING/SET register in the VLYNQ module and calls the 
     5661+ *  appropriate ISR associated with the correponding vector number. 
     5662+ * ----------------------------------------------------------------------------- 
     5663+ */ 
     5664+void vlynq_root_isr(void *arg) 
     5665+{ 
     5666+    int    source;  /* Bit position of pending interrupt, start from 0 */ 
     5667+    unsigned int interrupts, clrInterrupts; 
     5668+    VLYNQ_DEV * pdev; 
     5669+    VLYNQ_INTR_CNTRL_ICB *entry; 
     5670+ 
     5671+    pdev=(VLYNQ_DEV*)(arg);          /*obtain the vlynq device pointer*/ 
     5672+  
     5673+    interrupts =  VLYNQ_INT_STAT_REG; /* Get the list of pending interrupts */ 
     5674+    VLYNQ_INT_STAT_REG = interrupts; /* clear the int CR register */ 
     5675+    clrInterrupts = interrupts;      /* save them for further analysis */ 
     5676+ 
     5677+    debugPrint("vlynq_root_isr: dev %u. INTCR = 0x%08lx\n", pdev->dev_idx, clrInterrupts,0,0,0,0); 
     5678+ 
     5679+    /* Scan interrupt bits */ 
     5680+    source =0; 
     5681+    while( clrInterrupts != 0) 
     5682+    { 
     5683+        /* test if bit is set? */ 
     5684+        if( 0x1ul & clrInterrupts) 
     5685+        {    
     5686+            entry = &(pdev->pIntrCB[source]);   /* Get the ISR entry */ 
     5687+            pdev->intCount++;                   /* update interrupt count */     
     5688+            if(entry->isr != NULL) 
     5689+            { 
     5690+                do  
     5691+                { 
     5692+                    pdev->isrCount++;   /* update isr invocation count */     
     5693+                    /* Call the user ISR and update the count for ISR */ 
     5694+                   entry->isrCount++;    
     5695+                    entry->isr(entry->arg1, entry->arg2, entry->arg3); 
     5696+                    if (entry->next == NULL) break; 
     5697+                    entry = entry->next; 
     5698+ 
     5699+                } while (entry->isr != NULL); 
     5700+            } 
     5701+            else 
     5702+            {    
     5703+                debugPrint(" ISR not installed for vlynq vector:%d\n",source,0,0,0,0,0); 
     5704+            } 
     5705+        } 
     5706+        clrInterrupts >>= 1;    /* Next source bit */ 
     5707+        ++source; 
     5708+    } /* endWhile clrInterrupts != 0 */ 
     5709+} 
     5710+ 
     5711+ 
     5712+ /* ---------------------------------------------------------------------------- 
     5713+ *  Function : vlynq_local__module_isr() 
     5714+ *  Description: This ISR is attached to the local VLYNQ interrupt vector 
     5715+ *  by the Vlynq Driver when local interrupts are being handled. i.e. 
     5716+ *  intLocal=1. This ISR handles local Vlynq module status interrupts only 
     5717+ *  AS a part of this ISR, user callback in VLYNQ_DEV structure 
     5718+ *  is invoked. 
     5719+ *  VLYNQ_DEV is passed as arg1. arg2 and arg3 are unused. 
     5720+ * ----------------------------------------------------------------------------- 
     5721+ */ 
     5722+static void vlynq_local_module_isr(void *arg1,void *arg2, void *arg3) 
     5723+{ 
     5724+    VLYNQ_REPORT_CB func; 
     5725+    unsigned int dwStatRegVal; 
     5726+    VLYNQ_DEV * pdev; 
     5727+ 
     5728+    pdev = (VLYNQ_DEV*) arg1; 
     5729+    /* Callback function is read from the device pointer that is passed as an argument */ 
     5730+    func = pdev->report_cb; 
     5731+ 
     5732+    /* read local status register */ 
     5733+    dwStatRegVal = VLYNQ_STATUS_REG; 
     5734+ 
     5735+    /* clear pending events */ 
     5736+    VLYNQ_STATUS_REG = dwStatRegVal; 
     5737+    
     5738+    /* invoke user callback */ 
     5739+    if( func != NULL) 
     5740+        func( pdev, VLYNQ_LOCAL_DVC, dwStatRegVal); 
     5741+ 
     5742+} 
     5743+ 
     5744+ /* ---------------------------------------------------------------------------- 
     5745+ *  Function : vlynq_remote_module_isr() 
     5746+ *  Description: This ISR is attached to the remote VLYNQ interrupt vector 
     5747+ *  by the Vlynq Driver when remote interrupts are being handled locally. i.e. 
     5748+ *  intLocal=1. This ISR handles local Vlynq module status interrupts only 
     5749+ *  AS a part of this ISR, user callback in VLYNQ_DEV structure 
     5750+ *  is invoked. 
     5751+ *  The parameters  irq,regs ar unused. 
     5752+ * ----------------------------------------------------------------------------- 
     5753+ */ 
     5754+static void vlynq_remote_module_isr(void *arg1,void *arg2, void *arg3) 
     5755+{ 
     5756+    VLYNQ_REPORT_CB func; 
     5757+    unsigned int dwStatRegVal; 
     5758+    VLYNQ_DEV * pdev; 
     5759+ 
     5760+    
     5761+    pdev = (VLYNQ_DEV*) arg1; 
     5762+    
     5763+    /* Callback function is read from the device pointer that is passed as an argument */ 
     5764+   func = pdev->report_cb; 
     5765+ 
     5766+    /* read local status register */ 
     5767+    dwStatRegVal = VLYNQ_R_STATUS_REG; 
     5768+ 
     5769+    /* clear pending events */ 
     5770+    VLYNQ_R_STATUS_REG = dwStatRegVal; 
     5771+ 
     5772+    /* invoke user callback */ 
     5773+    if( func != NULL) 
     5774+        func( pdev, VLYNQ_REMOTE_DVC, dwStatRegVal); 
     5775+ 
     5776+} 
     5777+ 
     5778+/* ---------------------------------------------------------------------------- 
     5779+ *  Function : vlynq_interrupt_get_count() 
     5780+ *  Description: This function returns the number of times a particular intr 
     5781+ *  has been invoked.  
     5782+ * 
     5783+ *  It returns 0, if erroneous map_vector is specified or if the corres isr  
     5784+ *  has not been registered with VLYNQ. 
     5785+ */ 
     5786+unsigned int vlynq_interrupt_get_count(VLYNQ_DEV *pdev, 
     5787+                                       unsigned int map_vector) 
     5788+{ 
     5789+    VLYNQ_INTR_CNTRL_ICB *entry; 
     5790+    unsigned int count = 0; 
     5791+ 
     5792+    if (map_vector > (VLYNQ_NUM_INT_BITS-1))  
     5793+        return count; 
     5794+    
     5795+    entry = &(pdev->pIntrCB[map_vector]); 
     5796+ 
     5797+    if (entry) 
     5798+        count = entry->isrCount; 
     5799+ 
     5800+    return (count); 
     5801+} 
     5802+ 
     5803+ 
     5804+/* ---------------------------------------------------------------------------- 
     5805+ *  Function : vlynq_install_isr() 
     5806+ *  Description: This function installs ISR for Vlynq interrupt vector 
     5807+ *  bits(in IntPending register). This function should be used only when  
     5808+ *  Vlynq interrupts are being handled locally(remote may be programmed to send 
     5809+ *  interrupt packets).Also, the int2cfg should be 1 and the least significant 
     5810+ *  8 bits of the Interrupt Pointer Register must point to Interrupt  
     5811+ *  Pending/Set Register). 
     5812+ *  If host int2cfg=0 and the Interrupt Pointer register contains  
     5813+ *  the address of the interrupt set register in the interrupt controller  
     5814+ *  module of the local device , then the ISR for the remote interrupt must be  
     5815+ *  directly registered with the Interrupt controller and must not use this API 
     5816+ *  Note: this function simply installs the ISR in ICB It doesnt modify 
     5817+ *  any register settings 
     5818+ */ 
     5819+int  
     5820+vlynq_install_isr(VLYNQ_DEV *pdev, 
     5821+                  unsigned int map_vector, 
     5822+                  VLYNQ_INTR_CNTRL_ISR isr, 
     5823+                  void *arg1, void *arg2, void *arg3) 
     5824+{ 
     5825+    VLYNQ_INTR_CNTRL_ICB *entry; 
     5826+ 
     5827+    if ( (map_vector > (VLYNQ_NUM_INT_BITS-1)) || (isr == NULL) )  
     5828+        return VLYNQ_INVALID_ARG; 
     5829+    
     5830+    entry = &(pdev->pIntrCB[map_vector]); 
     5831+ 
     5832+    if(entry->isr == NULL) 
     5833+    { 
     5834+        entry->isr = isr; 
     5835+        entry->arg1 = arg1; 
     5836+        entry->arg2 = arg2; 
     5837+        entry->arg3 = arg3; 
     5838+        entry->next = NULL; 
     5839+    } 
     5840+    else 
     5841+    { 
     5842+        /** No more empty slots,return error */ 
     5843+        if(pdev->freelist == NULL) 
     5844+            return VLYNQ_MEMALLOC_FAIL; 
     5845+         
     5846+        while(entry->next != NULL) 
     5847+        { 
     5848+            entry = entry->next; 
     5849+        } 
     5850+ 
     5851+        /* Append new node to the chain */ 
     5852+        entry->next = pdev->freelist;    
     5853+        /* Remove the appended node from freelist */ 
     5854+        pdev->freelist = pdev->freelist->next;   
     5855+        entry= entry->next; 
     5856+          
     5857+        /*** Set the ICB fields ***/ 
     5858+        entry->isr = isr; 
     5859+        entry->arg1 = arg1; 
     5860+        entry->arg2 = arg2; 
     5861+        entry->arg3 = arg3; 
     5862+        entry->next = NULL; 
     5863+    } 
     5864+    
     5865+    return VLYNQ_SUCCESS; 
     5866+} 
     5867+ 
     5868+ 
     5869+ 
     5870+/* ---------------------------------------------------------------------------- 
     5871+ *  Function : vlynq_uninstall_isr 
     5872+ *  Description: This function is used to uninstall a previously 
     5873+ *  registered ISR. In case of shared/chained interrupts, the  
     5874+ *  void * arg parameter must uniquely identify the ISR to be 
     5875+ *  uninstalled. 
     5876+ *  Note: this function simply uninstalls the ISR in ICB 
     5877+ *  It doesnt modify any register settings 
     5878+ */ 
     5879+int  
     5880+vlynq_uninstall_isr(VLYNQ_DEV *pdev, 
     5881+                    unsigned int map_vector, 
     5882+                    void *arg1, void *arg2, void *arg3)  
     5883+{ 
     5884+    VLYNQ_INTR_CNTRL_ICB *entry,*temp; 
     5885+ 
     5886+    if (map_vector > (VLYNQ_NUM_INT_BITS-1))  
     5887+        return VLYNQ_INVALID_ARG; 
     5888+    
     5889+    entry = &(pdev->pIntrCB[map_vector]); 
     5890+ 
     5891+    if(entry->isr == NULL )  
     5892+        return VLYNQ_ISR_NON_EXISTENT; 
     5893+ 
     5894+    if ( (entry->arg1 == arg1) && (entry->arg2 == arg2) && (entry->arg3 == arg3) ) 
     5895+    { 
     5896+        if(entry->next == NULL) 
     5897+        { 
     5898+            entry->isr=NULL; 
     5899+            return VLYNQ_SUCCESS; 
     5900+        } 
     5901+        else 
     5902+        { 
     5903+            temp =  entry->next; 
     5904+            /* Copy next node in the chain to prim.slot */ 
     5905+            entry->isr = temp->isr; 
     5906+            entry->arg1 = temp->arg1; 
     5907+            entry->arg2 = temp->arg2; 
     5908+            entry->arg3 = temp->arg3; 
     5909+            entry->next = temp->next; 
     5910+            /* Free the just copied node */ 
     5911+            temp->isr = NULL; 
     5912+            temp->arg1 = NULL; 
     5913+            temp->arg2 = NULL; 
     5914+            temp->arg3 = NULL; 
     5915+            temp->next = pdev->freelist; 
     5916+            pdev->freelist = temp; 
     5917+            return VLYNQ_SUCCESS; 
     5918+        } 
     5919+    } 
     5920+    else 
     5921+    { 
     5922+        temp = entry; 
     5923+        while ( (entry = temp->next) != NULL) 
     5924+        { 
     5925+            if ( (entry->arg1 == arg1) && (entry->arg2 == arg2) && (entry->arg3 == arg3) ) 
     5926+            { 
     5927+                /* remove node from chain */ 
     5928+                temp->next = entry->next;  
     5929+                /* Add the removed node to freelist */ 
     5930+                entry->isr = NULL; 
     5931+                entry->arg1 = NULL; 
     5932+                entry->arg2 = NULL; 
     5933+                entry->arg3 = NULL; 
     5934+                entry->next = pdev->freelist; 
     5935+                entry->isrCount = 0; 
     5936+                pdev->freelist  = entry; 
     5937+                return VLYNQ_SUCCESS; 
     5938+            } 
     5939+            temp = entry; 
     5940+        } 
     5941+     
     5942+        return VLYNQ_ISR_NON_EXISTENT; 
     5943+    } 
     5944+} 
     5945+ 
     5946+ 
     5947+ 
     5948+ 
     5949+/* ---------------------------------------------------------------------------- 
     5950+ *  function : vlynq_interrupt_vector_set() 
     5951+ *  description:configures interrupt vector mapping,interrupt type 
     5952+ *  polarity -all in one go. 
     5953+ */ 
     5954+int  
     5955+vlynq_interrupt_vector_set(VLYNQ_DEV *pdev,                 /* vlynq device */ 
     5956+                           unsigned int int_vector,               /* int vector on vlynq device */ 
     5957+                           unsigned int map_vector,               /* bit for this interrupt */ 
     5958+                           VLYNQ_DEV_TYPE dev_type,         /* local or remote device */ 
     5959+                           VLYNQ_INTR_POLARITY pol,         /* polarity of interrupt */ 
     5960+                           VLYNQ_INTR_TYPE type)            /* pulsed/level interrupt */ 
     5961+{ 
     5962+    volatile unsigned int * vecreg; 
     5963+    unsigned int val=0; 
     5964+    unsigned int bytemask=0XFF; 
     5965+ 
     5966+    /* use the lower 8 bits of val to set the value , shift it to  
     5967+     * appropriate byte position in the ivr and write it to the  
     5968+     * corresponding register */ 
     5969+ 
     5970+    /* validate the number of interrupts supported */ 
     5971+    if (int_vector >= VLYNQ_IVR_MAXIVR)  
     5972+        return VLYNQ_INVALID_ARG; 
     5973+         
     5974+    if(map_vector > (VLYNQ_NUM_INT_BITS - 1) )  
     5975+        return VLYNQ_INVALID_ARG; 
     5976+ 
     5977+    if (dev_type == VLYNQ_LOCAL_DVC) 
     5978+    { 
     5979+        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); 
     5980+    } 
     5981+    else 
     5982+    { 
     5983+        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));   
     5984+    } 
     5985+ 
     5986+    /* Update the intVector<==> bit position translation table */ 
     5987+    pdev->vector_map[map_vector] = int_vector; 
     5988+ 
     5989+    /* val has been initialised to zero. we only have to turn on appropriate bits*/ 
     5990+    if(type == VLYNQ_INTR_PULSED) 
     5991+        val |= VLYNQ_IVR_INTTYPE_MASK; 
     5992+         
     5993+    if(pol == VLYNQ_INTR_ACTIVE_LOW) 
     5994+        val |= VLYNQ_IVR_INTPOL_MASK; 
     5995+ 
     5996+    val |= map_vector; 
     5997+ 
     5998+    /** clear the correct byte position and then or val **/ 
     5999+    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); 
     6000+ 
     6001+    /** write to correct byte position in vecreg*/ 
     6002+    *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; 
     6003+ 
     6004+    /* Setting a interrupt vector, leaves the interrupt disabled  
     6005+     * which  must be enabled subsequently */ 
     6006+ 
     6007+    return VLYNQ_SUCCESS; 
     6008+} 
     6009+ 
     6010+ 
     6011+/* ---------------------------------------------------------------------------- 
     6012+ *  Function : vlynq_interrupt_vector_cntl() 
     6013+ *  Description:enables/disable interrupt 
     6014+ */ 
     6015+int vlynq_interrupt_vector_cntl( VLYNQ_DEV *pdev, 
     6016+                                          unsigned int int_vector, 
     6017+                                          VLYNQ_DEV_TYPE dev_type, 
     6018+                                          unsigned int enable) 
     6019+{ 
     6020+    volatile unsigned int *vecReg; 
     6021+    unsigned int val=0; 
     6022+    unsigned int intenMask=0x80; 
     6023+ 
     6024+    /* validate the number of interrupts supported */ 
     6025+    if (int_vector >= VLYNQ_IVR_MAXIVR)  
     6026+        return VLYNQ_INVALID_ARG; 
     6027+ 
     6028+    if (dev_type == VLYNQ_LOCAL_DVC) 
     6029+    { 
     6030+        vecReg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); 
     6031+    } 
     6032+    else 
     6033+    { 
     6034+        vecReg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));   
     6035+    } 
     6036+ 
     6037+    /** Clear the correct byte position and then or val **/ 
     6038+    *vecReg = (*vecReg) & ( ~(intenMask << ( (int_vector %4)*8) ) ); 
     6039+ 
     6040+    if(enable) 
     6041+    { 
     6042+        val |= VLYNQ_IVR_INTEN_MASK;  
     6043+        /** Write to correct byte position in vecReg*/ 
     6044+        *vecReg = (*vecReg) | (val << ( (int_vector % 4)*8) ) ; 
     6045+    } 
     6046+ 
     6047+    return VLYNQ_SUCCESS; 
     6048+ 
     6049+}/* end of function vlynq_interrupt_vector_cntl */ 
     6050+ 
     6051+ 
     6052+ 
     6053+/* ---------------------------------------------------------------------------- 
     6054+ *  Function : vlynq_interrupt_vector_map() 
     6055+ *  Description:Configures interrupt vector mapping alone 
     6056+ */ 
     6057+int  
     6058+vlynq_interrupt_vector_map( VLYNQ_DEV *pdev, 
     6059+                            VLYNQ_DEV_TYPE dev_type, 
     6060+                            unsigned int int_vector, 
     6061+                            unsigned int map_vector) 
     6062+{ 
     6063+    volatile unsigned int * vecreg; 
     6064+    unsigned int val=0; 
     6065+    unsigned int bytemask=0x1f;   /* mask to turn off bits corresponding to int vector */  
     6066+ 
     6067+    /* use the lower 8 bits of val to set the value , shift it to  
     6068+     * appropriate byte position in the ivr and write it to the  
     6069+     * corresponding register */ 
     6070+ 
     6071+    /* validate the number of interrupts supported */ 
     6072+    if (int_vector >= VLYNQ_IVR_MAXIVR)  
     6073+        return VLYNQ_INVALID_ARG; 
     6074+         
     6075+    if(map_vector > (VLYNQ_NUM_INT_BITS - 1) )  
     6076+        return VLYNQ_INVALID_ARG; 
     6077+ 
     6078+    if (dev_type == VLYNQ_LOCAL_DVC) 
     6079+    { 
     6080+        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); 
     6081+    } 
     6082+    else 
     6083+    { 
     6084+        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));   
     6085+    } 
     6086+ 
     6087+    /* Update the intVector<==> bit position translation table */ 
     6088+    pdev->vector_map[map_vector] = int_vector; 
     6089+ 
     6090+    /** val has been initialised to zero. we only have to turn on 
     6091+     * appropriate bits*/ 
     6092+    val |= map_vector; 
     6093+ 
     6094+    /** clear the correct byte position and then or val **/ 
     6095+    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); 
     6096+ 
     6097+    /** write to correct byte position in vecreg*/ 
     6098+    *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; 
     6099+ 
     6100+    return VLYNQ_SUCCESS; 
     6101+} 
     6102+ 
     6103+ 
     6104+/* ---------------------------------------------------------------------------- 
     6105+ *  function : vlynq_interrupt_set_polarity() 
     6106+ *  description:configures interrupt polarity . 
     6107+ */ 
     6108+int  
     6109+vlynq_interrupt_set_polarity( VLYNQ_DEV *pdev , 
     6110+                              VLYNQ_DEV_TYPE dev_type, 
     6111+                              unsigned int map_vector, 
     6112+                              VLYNQ_INTR_POLARITY pol) 
     6113+{ 
     6114+    volatile unsigned int * vecreg; 
     6115+    int int_vector; 
     6116+    unsigned int val=0; 
     6117+    unsigned int bytemask=0x20; /** mask to turn off bits corresponding to int polarity */ 
     6118+ 
     6119+    /* get the int_vector from map_vector */ 
     6120+    int_vector = pdev->vector_map[map_vector]; 
     6121+ 
     6122+    if(int_vector == -1)  
     6123+        return VLYNQ_INTVEC_MAP_NOT_FOUND; 
     6124+ 
     6125+    /* use the lower 8 bits of val to set the value , shift it to  
     6126+     * appropriate byte position in the ivr and write it to the  
     6127+     * corresponding register */ 
     6128+ 
     6129+    if (dev_type == VLYNQ_LOCAL_DVC) 
     6130+    { 
     6131+        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); 
     6132+    } 
     6133+    else 
     6134+    { 
     6135+        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));   
     6136+    } 
     6137+ 
     6138+    /* val has been initialised to zero. we only have to turn on 
     6139+     * appropriate bits, if need be*/ 
     6140+ 
     6141+    /** clear the correct byte position and then or val **/ 
     6142+    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); 
     6143+ 
     6144+    if( pol == VLYNQ_INTR_ACTIVE_LOW) 
     6145+    { 
     6146+        val |= VLYNQ_IVR_INTPOL_MASK; 
     6147+        /** write to correct byte position in vecreg*/ 
     6148+        *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; 
     6149+    } 
     6150+ 
     6151+    return VLYNQ_SUCCESS; 
     6152+} 
     6153+ 
     6154+int vlynq_interrupt_get_polarity( VLYNQ_DEV *pdev , 
     6155+                                           VLYNQ_DEV_TYPE dev_type, 
     6156+                                           unsigned int map_vector) 
     6157+{ 
     6158+    volatile unsigned int * vecreg; 
     6159+    int int_vector; 
     6160+    unsigned int val=0; 
     6161+ 
     6162+    /* get the int_vector from map_vector */ 
     6163+    int_vector = pdev->vector_map[map_vector]; 
     6164+ 
     6165+    if (map_vector > (VLYNQ_NUM_INT_BITS-1)) 
     6166+        return(-1); 
     6167+ 
     6168+    if(int_vector == -1)  
     6169+        return VLYNQ_INTVEC_MAP_NOT_FOUND; 
     6170+ 
     6171+    /* use the lower 8 bits of val to set the value , shift it to  
     6172+     * appropriate byte position in the ivr and write it to the  
     6173+     * corresponding register */ 
     6174+ 
     6175+    if (dev_type == VLYNQ_LOCAL_DVC) 
     6176+    { 
     6177+        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); 
     6178+    } 
     6179+    else 
     6180+    { 
     6181+        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));   
     6182+    } 
     6183+ 
     6184+    /** read the information into val **/ 
     6185+    val = (*vecreg) & ((VLYNQ_IVR_INTPOL_MASK << ( (int_vector %4)*8) ) ); 
     6186+     
     6187+    return (val ? (VLYNQ_INTR_ACTIVE_LOW) : (VLYNQ_INTR_ACTIVE_HIGH)); 
     6188+} 
     6189+ 
     6190+ 
     6191+/* ---------------------------------------------------------------------------- 
     6192+ *  function : vlynq_interrupt_set_type() 
     6193+ *  description:configures interrupt type . 
     6194+ */ 
     6195+int vlynq_interrupt_set_type( VLYNQ_DEV *pdev, 
     6196+                                       VLYNQ_DEV_TYPE dev_type, 
     6197+                                       unsigned int map_vector, 
     6198+                                       VLYNQ_INTR_TYPE type) 
     6199+{ 
     6200+    volatile unsigned int * vecreg; 
     6201+    unsigned int val=0; 
     6202+    int int_vector; 
     6203+ 
     6204+    /** mask to turn off bits corresponding to interrupt type */ 
     6205+    unsigned int bytemask=0x40; 
     6206+ 
     6207+    /* get the int_vector from map_vector */ 
     6208+    int_vector = pdev->vector_map[map_vector]; 
     6209+    if(int_vector == -1)  
     6210+        return VLYNQ_INTVEC_MAP_NOT_FOUND; 
     6211+ 
     6212+    /* use the lower 8 bits of val to set the value , shift it to  
     6213+     * appropriate byte position in the ivr and write it to the  
     6214+     * corresponding register */ 
     6215+    if (dev_type == VLYNQ_LOCAL_DVC) 
     6216+    { 
     6217+        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); 
     6218+    } 
     6219+    else 
     6220+    { 
     6221+        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));   
     6222+    } 
     6223+ 
     6224+    /** val has been initialised to zero. we only have to turn on 
     6225+     * appropriate bits if need be*/ 
     6226+ 
     6227+     /** clear the correct byte position and then or val **/ 
     6228+    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); 
     6229+ 
     6230+    if( type == VLYNQ_INTR_PULSED) 
     6231+    { 
     6232+        val |= VLYNQ_IVR_INTTYPE_MASK; 
     6233+        /** write to correct byte position in vecreg*/ 
     6234+        *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; 
     6235+    } 
     6236+ 
     6237+    return VLYNQ_SUCCESS; 
     6238+} 
     6239+ 
     6240+/* ---------------------------------------------------------------------------- 
     6241+ *  function : vlynq_interrupt_get_type() 
     6242+ *  description:returns interrupt type . 
     6243+ */ 
     6244+int vlynq_interrupt_get_type( VLYNQ_DEV *pdev, VLYNQ_DEV_TYPE dev_type, 
     6245+                                       unsigned int map_vector) 
     6246+{ 
     6247+    volatile unsigned int * vecreg; 
     6248+    unsigned int val=0; 
     6249+    int int_vector; 
     6250+ 
     6251+    if (map_vector > (VLYNQ_NUM_INT_BITS-1)) 
     6252+        return(-1); 
     6253+ 
     6254+    /* get the int_vector from map_vector */ 
     6255+    int_vector = pdev->vector_map[map_vector]; 
     6256+    if(int_vector == -1)  
     6257+        return VLYNQ_INTVEC_MAP_NOT_FOUND; 
     6258+ 
     6259+    /* use the lower 8 bits of val to set the value , shift it to  
     6260+     * appropriate byte position in the ivr and write it to the  
     6261+     * corresponding register */ 
     6262+    if (dev_type == VLYNQ_LOCAL_DVC) 
     6263+    { 
     6264+        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); 
     6265+    } 
     6266+    else 
     6267+    { 
     6268+        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));   
     6269+    } 
     6270+ 
     6271+    /** Read the correct bit position into val **/ 
     6272+    val = (*vecreg) & ((VLYNQ_IVR_INTTYPE_MASK << ( (int_vector %4)*8) ) ); 
     6273+ 
     6274+    return (val ? (VLYNQ_INTR_PULSED) : (VLYNQ_INTR_LEVEL)); 
     6275+} 
     6276+ 
     6277+/* ---------------------------------------------------------------------------- 
     6278+ *  function : vlynq_interrupt_enable() 
     6279+ *  description:Enable interrupt by writing to IVR register. 
     6280+ */ 
     6281+int vlynq_interrupt_enable( VLYNQ_DEV *pdev, 
     6282+                                     VLYNQ_DEV_TYPE dev_type, 
     6283+                                     unsigned int map_vector) 
     6284+{ 
     6285+    volatile unsigned int * vecreg; 
     6286+    unsigned int val=0; 
     6287+    int int_vector; 
     6288+ 
     6289+    /** mask to turn off bits corresponding to interrupt enable */ 
     6290+    unsigned int bytemask=0x80; 
     6291+ 
     6292+    /* get the int_vector from map_vector */ 
     6293+    int_vector = pdev->vector_map[map_vector]; 
     6294+    if(int_vector == -1)  
     6295+        return VLYNQ_INTVEC_MAP_NOT_FOUND; 
     6296+ 
     6297+    /* use the lower 8 bits of val to set the value , shift it to  
     6298+     * appropriate byte position in the ivr and write it to the  
     6299+     * corresponding register */ 
     6300+ 
     6301+    if (dev_type == VLYNQ_LOCAL_DVC) 
     6302+    { 
     6303+        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); 
     6304+    } 
     6305+    else 
     6306+    { 
     6307+        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));   
     6308+    } 
     6309+ 
     6310+    /** val has been initialised to zero. we only have to turn on 
     6311+    *  bit corresponding to interrupt enable*/ 
     6312+    val |= VLYNQ_IVR_INTEN_MASK; 
     6313+ 
     6314+    /** clear the correct byte position and then or val **/ 
     6315+    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); 
     6316+ 
     6317+    /** write to correct byte position in vecreg*/ 
     6318+    *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; 
     6319+ 
     6320+    return VLYNQ_SUCCESS; 
     6321+} 
     6322+ 
     6323+ 
     6324+/* ---------------------------------------------------------------------------- 
     6325+ *  function : vlynq_interrupt_disable() 
     6326+ *  description:Disable interrupt by writing to IVR register. 
     6327+ */ 
     6328+int  
     6329+vlynq_interrupt_disable( VLYNQ_DEV *pdev, 
     6330+                         VLYNQ_DEV_TYPE dev_type, 
     6331+                         unsigned int map_vector) 
     6332+{ 
     6333+    volatile unsigned int * vecreg; 
     6334+    int int_vector; 
     6335+ 
     6336+    /** mask to turn off bits corresponding to interrupt enable */ 
     6337+    unsigned int bytemask=0x80; 
     6338+ 
     6339+    /* get the int_vector from map_vector */ 
     6340+    int_vector = pdev->vector_map[map_vector]; 
     6341+    if(int_vector == -1)  
     6342+        return VLYNQ_INTVEC_MAP_NOT_FOUND; 
     6343+ 
     6344+    /* use the lower 8 bits of val to set the value , shift it to  
     6345+     * appropriate byte position in the ivr and write it to the  
     6346+     * corresponding register */ 
     6347+    if (dev_type == VLYNQ_LOCAL_DVC) 
     6348+    { 
     6349+        vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); 
     6350+    } 
     6351+    else 
     6352+    { 
     6353+        vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector));   
     6354+    } 
     6355+ 
     6356+    /* We disable the interrupt by simply turning off the bit 
     6357+     * corresponding to Interrupt enable.  
     6358+     * Clear the interrupt enable bit in the correct byte position **/ 
     6359+    *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); 
     6360+ 
     6361+    /* Dont have to set any bit positions */ 
     6362+ 
     6363+    return VLYNQ_SUCCESS; 
     6364+ 
     6365+} 
     6366+ 
     6367+ 
     6368+ 
     6369+ 
    36086370diff -urN linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c 
    3609 --- linux.old/drivers/char/serial.c     2005-07-10 03:00:44.000000000 +0200 
    3610 +++ linux.dev/drivers/char/serial.c     2005-08-12 19:32:05.147223992 +0200 
     6371--- linux.old/drivers/char/serial.c     2005-10-21 16:43:20.709226000 +0200 
     6372+++ linux.dev/drivers/char/serial.c     2005-10-21 16:45:42.166066500 +0200 
    36116373@@ -419,7 +419,40 @@ 
    36126374        return 0; 
     
    36786440        /* If the quotient is zero refuse the change */ 
    36796441        if (!quot && old_termios) { 
    3680 @@ -5552,8 +5595,10 @@ 
     6442@@ -5540,8 +5583,10 @@ 
    36816443                state->irq = irq_cannonicalize(state->irq); 
    36826444                if (state->hub6) 
     
    36896451                if ((state->flags & ASYNC_BOOT_ONLYMCA) && !MCA_bus) 
    36906452                        continue; 
    3691 @@ -6009,7 +6054,15 @@ 
     6453@@ -5997,7 +6042,15 @@ 
    36926454        info->io_type = state->io_type; 
    36936455        info->iomem_base = state->iomem_base; 
     
    37056467 #if defined(__powerpc__) || defined(__alpha__) 
    37066468        cval >>= 8; 
     6469diff -urN linux.old/drivers/char/serial.c.orig linux.dev/drivers/char/serial.c.orig 
     6470--- linux.old/drivers/char/serial.c.orig        1970-01-01 01:00:00.000000000 +0100 
     6471+++ linux.dev/drivers/char/serial.c.orig        2005-10-21 16:43:20.709226000 +0200 
     6472@@ -0,0 +1,6054 @@ 
     6473+/* 
     6474+ *  linux/drivers/char/serial.c 
     6475+ * 
     6476+ *  Copyright (C) 1991, 1992  Linus Torvalds 
     6477+ *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997,  
     6478+ *             1998, 1999  Theodore Ts'o 
     6479+ * 
     6480+ *  Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92.  Now 
     6481+ *  much more extensible to support other serial cards based on the 
     6482+ *  16450/16550A UART's.  Added support for the AST FourPort and the 
     6483+ *  Accent Async board.   
     6484+ * 
     6485+ *  set_serial_info fixed to set the flags, custom divisor, and uart 
     6486+ *     type fields.  Fix suggested by Michael K. Johnson 12/12/92. 
     6487+ * 
     6488+ *  11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk> 
     6489+ * 
     6490+ *  03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk> 
     6491+ * 
     6492+ *  rs_set_termios fixed to look also for changes of the input 
     6493+ *      flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK. 
     6494+ *                                            Bernd Anhäupl 05/17/96. 
     6495+ * 
     6496+ *  1/97:  Extended dumb serial ports are a config option now.   
     6497+ *         Saves 4k.   Michael A. Griffith <grif@acm.org> 
     6498+ *  
     6499+ *  8/97: Fix bug in rs_set_termios with RTS 
     6500+ *        Stanislav V. Voronyi <stas@uanet.kharkov.ua> 
     6501+ * 
     6502+ *  3/98: Change the IRQ detection, use of probe_irq_o*(), 
     6503+ *       suppress TIOCSERGWILD and TIOCSERSWILD 
     6504+ *       Etienne Lorrain <etienne.lorrain@ibm.net> 
     6505+ * 
     6506+ *  4/98: Added changes to support the ARM architecture proposed by 
     6507+ *       Russell King 
     6508+ * 
     6509+ *  5/99: Updated to include support for the XR16C850 and ST16C654 
     6510+ *        uarts.  Stuart MacDonald <stuartm@connecttech.com> 
     6511+ * 
     6512+ *  8/99: Generalized PCI support added.  Theodore Ts'o 
     6513+ *  
     6514+ *  3/00: Rid circular buffer of redundant xmit_cnt.  Fix a 
     6515+ *       few races on freeing buffers too. 
     6516+ *       Alan Modra <alan@linuxcare.com> 
     6517+ * 
     6518+ *  5/00: Support for the RSA-DV II/S card added. 
     6519+ *       Kiyokazu SUTO <suto@ks-and-ks.ne.jp> 
     6520+ *  
     6521+ *  6/00: Remove old-style timer, use timer_list 
     6522+ *        Andrew Morton <andrewm@uow.edu.au> 
     6523+ * 
     6524+ *  7/00: Support Timedia/Sunix/Exsys PCI cards 
     6525+ * 
     6526+ *  7/00: fix some returns on failure not using MOD_DEC_USE_COUNT. 
     6527+ *       Arnaldo Carvalho de Melo <acme@conectiva.com.br> 
     6528+ * 
     6529+ * 10/00: add in optional software flow control for serial console. 
     6530+ *       Kanoj Sarcar <kanoj@sgi.com>  (Modified by Theodore Ts'o) 
     6531+ * 
     6532+ * 02/02: Fix for AMD Elan bug in transmit irq routine, by 
     6533+ *        Christer Weinigel <wingel@hog.ctrl-c.liu.se>, 
     6534+ *        Robert Schwebel <robert@schwebel.de>, 
     6535+ *        Juergen Beisert <jbeisert@eurodsn.de>, 
     6536+ *        Theodore Ts'o <tytso@mit.edu> 
     6537+ * 
     6538+ * 10/00: Added suport for MIPS Atlas board. 
     6539+ * 11/00: Hooks for serial kernel debug port support added. 
     6540+ *        Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, 
     6541+ *        carstenl@mips.com 
     6542+ *        Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved. 
     6543+ */ 
     6544+ 
     6545+static char *serial_version = "5.05c"; 
     6546+static char *serial_revdate = "2001-07-08"; 
     6547+ 
     6548+/* 
     6549+ * Serial driver configuration section.  Here are the various options: 
     6550+ * 
     6551+ * CONFIG_HUB6 
     6552+ *             Enables support for the venerable Bell Technologies 
     6553+ *             HUB6 card. 
     6554+ * 
     6555+ * CONFIG_SERIAL_MANY_PORTS 
     6556+ *             Enables support for ports beyond the standard, stupid 
     6557+ *             COM 1/2/3/4. 
     6558+ * 
     6559+ * CONFIG_SERIAL_MULTIPORT 
     6560+ *             Enables support for special multiport board support. 
     6561+ * 
     6562+ * CONFIG_SERIAL_SHARE_IRQ 
     6563+ *             Enables support for multiple serial ports on one IRQ 
     6564+ * 
     6565+ * CONFIG_SERIAL_DETECT_IRQ 
     6566+ *             Enable the autodetection of IRQ on standart ports 
     6567+ * 
     6568+ * SERIAL_PARANOIA_CHECK 
     6569+ *             Check the magic number for the async_structure where 
     6570+ *             ever possible. 
     6571+ * 
     6572+ * CONFIG_SERIAL_ACPI 
     6573+ *             Enable support for serial console port and serial  
     6574+ *             debug port as defined by the SPCR and DBGP tables in  
     6575+ *             ACPI 2.0. 
     6576+ */ 
     6577+ 
     6578+#include <linux/config.h> 
     6579+#include <linux/version.h> 
     6580+ 
     6581+#undef SERIAL_PARANOIA_CHECK 
     6582+#define CONFIG_SERIAL_NOPAUSE_IO 
     6583+#define SERIAL_DO_RESTART 
     6584+ 
     6585+#if 0 
     6586+/* These defines are normally controlled by the autoconf.h */ 
     6587+#define CONFIG_SERIAL_MANY_PORTS 
     6588+#define CONFIG_SERIAL_SHARE_IRQ 
     6589+#define CONFIG_SERIAL_DETECT_IRQ 
     6590+#define CONFIG_SERIAL_MULTIPORT 
     6591+#define CONFIG_HUB6 
     6592+#endif 
     6593+ 
     6594+#ifdef CONFIG_PCI 
     6595+#define ENABLE_SERIAL_PCI 
     6596+#ifndef CONFIG_SERIAL_SHARE_IRQ 
     6597+#define CONFIG_SERIAL_SHARE_IRQ 
     6598+#endif 
     6599+#ifndef CONFIG_SERIAL_MANY_PORTS 
     6600+#define CONFIG_SERIAL_MANY_PORTS 
     6601+#endif 
     6602+#endif 
     6603+ 
     6604+#ifdef CONFIG_SERIAL_ACPI 
     6605+#define ENABLE_SERIAL_ACPI 
     6606+#endif 
     6607+ 
     6608+#if defined(CONFIG_ISAPNP)|| (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE)) 
     6609+#ifndef ENABLE_SERIAL_PNP 
     6610+#define ENABLE_SERIAL_PNP 
     6611+#endif 
     6612+#endif 
     6613+ 
     6614+/* Set of debugging defines */ 
     6615+ 
     6616+#undef SERIAL_DEBUG_INTR 
     6617+#undef SERIAL_DEBUG_OPEN 
     6618+#undef SERIAL_DEBUG_FLOW 
     6619+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT 
     6620+#undef SERIAL_DEBUG_PCI 
     6621+#undef SERIAL_DEBUG_AUTOCONF 
     6622+ 
     6623+/* Sanity checks */ 
     6624+ 
     6625+#ifdef CONFIG_SERIAL_MULTIPORT 
     6626+#ifndef CONFIG_SERIAL_SHARE_IRQ 
     6627+#define CONFIG_SERIAL_SHARE_IRQ 
     6628+#endif 
     6629+#endif 
     6630+ 
     6631+#ifdef CONFIG_HUB6 
     6632+#ifndef CONFIG_SERIAL_MANY_PORTS 
     6633+#define CONFIG_SERIAL_MANY_PORTS 
     6634+#endif 
     6635+#ifndef CONFIG_SERIAL_SHARE_IRQ 
     6636+#define CONFIG_SERIAL_SHARE_IRQ 
     6637+#endif 
     6638+#endif 
     6639+ 
     6640+#ifdef MODULE 
     6641+#undef CONFIG_SERIAL_CONSOLE 
     6642+#endif 
     6643+ 
     6644+#define CONFIG_SERIAL_RSA 
     6645+ 
     6646+#define RS_STROBE_TIME (10*HZ) 
     6647+#define RS_ISR_PASS_LIMIT 256 
     6648+ 
     6649+#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486)) 
     6650+#define SERIAL_INLINE 
     6651+#endif 
     6652 
     6653+/* 
     6654+ * End of serial driver configuration section. 
     6655+ */ 
     6656+ 
     6657+#include <linux/module.h> 
     6658+ 
     6659+#include <linux/types.h> 
     6660+#ifdef LOCAL_HEADERS 
     6661+#include "serial_local.h" 
     6662+#else 
     6663+#include <linux/serial.h> 
     6664+#include <linux/serialP.h> 
     6665+#include <linux/serial_reg.h> 
     6666+#include <asm/serial.h> 
     6667+#define LOCAL_VERSTRING "" 
     6668+#endif 
     6669+ 
     6670+#include <linux/errno.h> 
     6671+#include <linux/signal.h> 
     6672+#include <linux/sched.h> 
     6673+#include <linux/timer.h> 
     6674+#include <linux/interrupt.h> 
     6675+#include <linux/tty.h> 
     6676+#include <linux/tty_flip.h> 
     6677+#include <linux/major.h> 
     6678+#include <linux/string.h> 
     6679+#include <linux/fcntl.h> 
     6680+#include <linux/ptrace.h> 
     6681+#include <linux/ioport.h> 
     6682+#include <linux/mm.h> 
     6683+#include <linux/slab.h> 
     6684+#if (LINUX_VERSION_CODE >= 131343) 
     6685+#include <linux/init.h> 
     6686+#endif 
     6687+#if (LINUX_VERSION_CODE >= 131336) 
     6688+#include <asm/uaccess.h> 
     6689+#endif 
     6690+#include <linux/delay.h> 
     6691+#ifdef CONFIG_SERIAL_CONSOLE 
     6692+#include <linux/console.h> 
     6693+#endif 
     6694+#ifdef ENABLE_SERIAL_PCI 
     6695+#include <linux/pci.h> 
     6696+#endif 
     6697+#ifdef ENABLE_SERIAL_PNP 
     6698+#include <linux/isapnp.h> 
     6699+#endif 
     6700+#ifdef CONFIG_MAGIC_SYSRQ 
     6701+#include <linux/sysrq.h> 
     6702+#endif 
     6703+ 
     6704+/* 
     6705+ * All of the compatibilty code so we can compile serial.c against 
     6706+ * older kernels is hidden in serial_compat.h 
     6707+ */ 
     6708+#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */ 
     6709+#include "serial_compat.h" 
     6710+#endif 
     6711+ 
     6712+#include <asm/system.h> 
     6713+#include <asm/io.h> 
     6714+#include <asm/irq.h> 
     6715+#include <asm/bitops.h> 
     6716+ 
     6717+#if defined(CONFIG_MAC_SERIAL) 
     6718+#define SERIAL_DEV_OFFSET      ((_machine == _MACH_prep || _machine == _MACH_chrp) ? 0 : 2) 
     6719+#else 
     6720+#define SERIAL_DEV_OFFSET      0 
     6721+#endif 
     6722+ 
     6723+#ifdef SERIAL_INLINE 
     6724+#define _INLINE_ inline 
     6725+#else 
     6726+#define _INLINE_ 
     6727+#endif 
     6728+ 
     6729+static char *serial_name = "Serial driver"; 
     6730+ 
     6731+static DECLARE_TASK_QUEUE(tq_serial); 
     6732+ 
     6733+static struct tty_driver serial_driver, callout_driver; 
     6734+static int serial_refcount; 
     6735+ 
     6736+static struct timer_list serial_timer; 
     6737+ 
     6738+/* serial subtype definitions */ 
     6739+#ifndef SERIAL_TYPE_NORMAL 
     6740+#define SERIAL_TYPE_NORMAL     1 
     6741+#define SERIAL_TYPE_CALLOUT    2 
     6742+#endif 
     6743+ 
     6744+/* number of characters left in xmit buffer before we ask for more */ 
     6745+#define WAKEUP_CHARS 256 
     6746+ 
     6747+/* 
     6748+ * IRQ_timeout         - How long the timeout should be for each IRQ 
     6749+ *                             should be after the IRQ has been active. 
     6750+ */ 
     6751+ 
     6752+static struct async_struct *IRQ_ports[NR_IRQS]; 
     6753+#ifdef CONFIG_SERIAL_MULTIPORT 
     6754+static struct rs_multiport_struct rs_multiport[NR_IRQS]; 
     6755+#endif 
     6756+static int IRQ_timeout[NR_IRQS]; 
     6757+#ifdef CONFIG_SERIAL_CONSOLE 
     6758+static struct console sercons; 
     6759+static int lsr_break_flag; 
     6760+#endif 
     6761+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 
     6762+static unsigned long break_pressed; /* break, really ... */ 
     6763+#endif 
     6764+ 
     6765+static unsigned detect_uart_irq (struct serial_state * state); 
     6766+static void autoconfig(struct serial_state * state); 
     6767+static void change_speed(struct async_struct *info, struct termios *old); 
     6768+static void rs_wait_until_sent(struct tty_struct *tty, int timeout); 
     6769+ 
     6770+/* 
     6771+ * Here we define the default xmit fifo size used for each type of 
     6772+ * UART 
     6773+ */ 
     6774+static struct serial_uart_config uart_config[] = { 
     6775+       { "unknown", 1, 0 },  
     6776+       { "8250", 1, 0 },  
     6777+       { "16450", 1, 0 },  
     6778+       { "16550", 1, 0 },  
     6779+       { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },  
     6780+       { "cirrus", 1, 0 },     /* usurped by cyclades.c */ 
     6781+       { "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },  
     6782+       { "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO | 
     6783+                 UART_STARTECH },  
     6784+       { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO}, 
     6785+       { "Startech", 1, 0},    /* usurped by cyclades.c */ 
     6786+       { "16C950/954", 128, UART_CLEAR_FIFO | UART_USE_FIFO}, 
     6787+       { "ST16654", 64, UART_CLEAR_FIFO | UART_USE_FIFO | 
     6788+                 UART_STARTECH },  
     6789+       { "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO | 
     6790+                 UART_STARTECH }, 
     6791+       { "RSA", 2048, UART_CLEAR_FIFO | UART_USE_FIFO },  
     6792+       { 0, 0} 
     6793+}; 
     6794+ 
     6795+#if defined(CONFIG_SERIAL_RSA) && defined(MODULE) 
     6796+ 
     6797+#define PORT_RSA_MAX 4 
     6798+static int probe_rsa[PORT_RSA_MAX]; 
     6799+static int force_rsa[PORT_RSA_MAX]; 
     6800+ 
     6801+MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i"); 
     6802+MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); 
     6803+MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i"); 
     6804+MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA"); 
     6805+#endif /* CONFIG_SERIAL_RSA  */ 
     6806+ 
     6807+struct serial_state rs_table[RS_TABLE_SIZE] = { 
     6808+       SERIAL_PORT_DFNS        /* Defined in serial.h */ 
     6809+}; 
     6810+ 
     6811+#define NR_PORTS       (sizeof(rs_table)/sizeof(struct serial_state)) 
     6812+int serial_nr_ports = NR_PORTS; 
     6813+ 
     6814+#if (defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)) 
     6815+#define NR_PCI_BOARDS  8 
     6816+ 
     6817+static struct pci_board_inst   serial_pci_board[NR_PCI_BOARDS]; 
     6818+ 
     6819+#ifndef IS_PCI_REGION_IOPORT 
     6820+#define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \ 
     6821+                                     IORESOURCE_IO) 
     6822+#endif 
     6823+#ifndef IS_PCI_REGION_IOMEM 
     6824+#define IS_PCI_REGION_IOMEM(dev, r) (pci_resource_flags((dev), (r)) & \ 
     6825+                                     IORESOURCE_MEM) 
     6826+#endif 
     6827+#ifndef PCI_IRQ_RESOURCE 
     6828+#define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq_resource[r].start) 
     6829+#endif 
     6830+#ifndef pci_get_subvendor 
     6831+#define pci_get_subvendor(dev) ((dev)->subsystem_vendor) 
     6832+#define pci_get_subdevice(dev)  ((dev)->subsystem_device) 
     6833+#endif 
     6834+#endif /* ENABLE_SERIAL_PCI || ENABLE_SERIAL_PNP  */ 
     6835+ 
     6836+#ifndef PREPARE_FUNC 
     6837+#define PREPARE_FUNC(dev)  (dev->prepare) 
     6838+#define ACTIVATE_FUNC(dev)  (dev->activate) 
     6839+#define DEACTIVATE_FUNC(dev)  (dev->deactivate) 
     6840+#endif 
     6841+ 
     6842+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) 
     6843+ 
     6844+static struct tty_struct *serial_table[NR_PORTS]; 
     6845+static struct termios *serial_termios[NR_PORTS]; 
     6846+static struct termios *serial_termios_locked[NR_PORTS]; 
     6847+ 
     6848+ 
     6849+#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) 
     6850+#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ 
     6851+ kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s) 
     6852+#else 
     6853+#define DBG_CNT(s) 
     6854+#endif 
     6855+ 
     6856+/* 
     6857+ * tmp_buf is used as a temporary buffer by serial_write.  We need to 
     6858+ * lock it in case the copy_from_user blocks while swapping in a page, 
     6859+ * and some other program tries to do a serial write at the same time. 
     6860+ * Since the lock will only come under contention when the system is 
     6861+ * swapping and available memory is low, it makes sense to share one 
     6862+ * buffer across all the serial ports, since it significantly saves 
     6863+ * memory if large numbers of serial ports are open. 
     6864+ */ 
     6865+static unsigned char *tmp_buf; 
     6866+#ifdef DECLARE_MUTEX 
     6867+static DECLARE_MUTEX(tmp_buf_sem); 
     6868+#else 
     6869+static struct semaphore tmp_buf_sem = MUTEX; 
     6870+#endif 
     6871+ 
     6872+ 
     6873+static inline int serial_paranoia_check(struct async_struct *info, 
     6874+                                       kdev_t device, const char *routine) 
     6875+{ 
     6876+#ifdef SERIAL_PARANOIA_CHECK 
     6877+       static const char *badmagic = 
     6878+               "Warning: bad magic number for serial struct (%s) in %s\n"; 
     6879+       static const char *badinfo = 
     6880+               "Warning: null async_struct for (%s) in %s\n"; 
     6881+ 
     6882+       if (!info) { 
     6883+               printk(badinfo, kdevname(device), routine); 
     6884+               return 1; 
     6885+       } 
     6886+       if (info->magic != SERIAL_MAGIC) { 
     6887+               printk(badmagic, kdevname(device), routine); 
     6888+               return 1; 
     6889+       } 
     6890+#endif 
     6891+       return 0; 
     6892+} 
     6893+ 
     6894+#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_SEAD) 
     6895+ 
     6896+#include <asm/mips-boards/atlas.h> 
     6897+ 
     6898+static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset) 
     6899+{ 
     6900+        return (*(volatile unsigned int *)(mips_io_port_base + ATLAS_UART_REGS_BASE + offset*8) & 0xff); 
     6901+} 
     6902+ 
     6903+static _INLINE_ void serial_out(struct async_struct *info, int offset, int value) 
     6904+{ 
     6905+        *(volatile unsigned int *)(mips_io_port_base + ATLAS_UART_REGS_BASE + offset*8) = value; 
     6906+} 
     6907+ 
     6908+#else 
     6909+ 
     6910+static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset) 
     6911+{ 
     6912+       switch (info->io_type) { 
     6913+#ifdef CONFIG_HUB6 
     6914+       case SERIAL_IO_HUB6: 
     6915+               outb(info->hub6 - 1 + offset, info->port); 
     6916+               return inb(info->port+1); 
     6917+#endif 
     6918+       case SERIAL_IO_MEM: 
     6919+               return readb((unsigned long) info->iomem_base + 
     6920+                            (offset<<info->iomem_reg_shift)); 
     6921+       default: 
     6922+               return inb(info->port + offset); 
     6923+       } 
     6924+} 
     6925+ 
     6926+static _INLINE_ void serial_out(struct async_struct *info, int offset, 
     6927+                               int value) 
     6928+{ 
     6929+       switch (info->io_type) { 
     6930+#ifdef CONFIG_HUB6 
     6931+       case SERIAL_IO_HUB6: 
     6932+               outb(info->hub6 - 1 + offset, info->port); 
     6933+               outb(value, info->port+1); 
     6934+               break; 
     6935+#endif 
     6936+       case SERIAL_IO_MEM: 
     6937+               writeb(value, (unsigned long) info->iomem_base + 
     6938+                             (offset<<info->iomem_reg_shift)); 
     6939+               break; 
     6940+       default: 
     6941+               outb(value, info->port+offset); 
     6942+       } 
     6943+} 
     6944+#endif 
     6945+ 
     6946+ 
     6947+/* 
     6948+ * We used to support using pause I/O for certain machines.  We 
     6949+ * haven't supported this for a while, but just in case it's badly 
     6950+ * needed for certain old 386 machines, I've left these #define's 
     6951+ * in.... 
     6952+ */ 
     6953+#define serial_inp(info, offset)               serial_in(info, offset) 
     6954+#define serial_outp(info, offset, value)       serial_out(info, offset, value) 
     6955+ 
     6956+ 
     6957+/* 
     6958+ * For the 16C950 
     6959+ */ 
     6960+void serial_icr_write(struct async_struct *info, int offset, int  value) 
     6961+{ 
     6962+       serial_out(info, UART_SCR, offset); 
     6963+       serial_out(info, UART_ICR, value); 
     6964+} 
     6965+ 
     6966+unsigned int serial_icr_read(struct async_struct *info, int offset) 
     6967+{ 
     6968+       int     value; 
     6969+ 
     6970+       serial_icr_write(info, UART_ACR, info->ACR | UART_ACR_ICRRD); 
     6971+       serial_out(info, UART_SCR, offset); 
     6972+       value = serial_in(info, UART_ICR); 
     6973+       serial_icr_write(info, UART_ACR, info->ACR); 
     6974+       return value; 
     6975+} 
     6976+ 
     6977+/* 
     6978+ * ------------------------------------------------------------ 
     6979+ * rs_stop() and rs_start() 
     6980+ * 
     6981+ * This routines are called before setting or resetting tty->stopped. 
     6982+ * They enable or disable transmitter interrupts, as necessary. 
     6983+ * ------------------------------------------------------------ 
     6984+ */ 
     6985+static void rs_stop(struct tty_struct *tty) 
     6986+{ 
     6987+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     6988+       unsigned long flags; 
     6989+ 
     6990+       if (serial_paranoia_check(info, tty->device, "rs_stop")) 
     6991+               return; 
     6992+        
     6993+       save_flags(flags); cli(); 
     6994+       if (info->IER & UART_IER_THRI) { 
     6995+               info->IER &= ~UART_IER_THRI; 
     6996+               serial_out(info, UART_IER, info->IER); 
     6997+       } 
     6998+       if (info->state->type == PORT_16C950) { 
     6999+               info->ACR |= UART_ACR_TXDIS; 
     7000+               serial_icr_write(info, UART_ACR, info->ACR); 
     7001+       } 
     7002+       restore_flags(flags); 
     7003+} 
     7004+ 
     7005+static void rs_start(struct tty_struct *tty) 
     7006+{ 
     7007+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     7008+       unsigned long flags; 
     7009+        
     7010+       if (serial_paranoia_check(info, tty->device, "rs_start")) 
     7011+               return; 
     7012+        
     7013+       save_flags(flags); cli(); 
     7014+       if (info->xmit.head != info->xmit.tail 
     7015+           && info->xmit.buf 
     7016+           && !(info->IER & UART_IER_THRI)) { 
     7017+               info->IER |= UART_IER_THRI; 
     7018+               serial_out(info, UART_IER, info->IER); 
     7019+       } 
     7020+       if (info->state->type == PORT_16C950) { 
     7021+               info->ACR &= ~UART_ACR_TXDIS; 
     7022+               serial_icr_write(info, UART_ACR, info->ACR); 
     7023+       } 
     7024+       restore_flags(flags); 
     7025+} 
     7026+ 
     7027+/* 
     7028+ * ---------------------------------------------------------------------- 
     7029+ * 
     7030+ * Here starts the interrupt handling routines.  All of the following 
     7031+ * subroutines are declared as inline and are folded into 
     7032+ * rs_interrupt().  They were separated out for readability's sake. 
     7033+ * 
     7034+ * Note: rs_interrupt() is a "fast" interrupt, which means that it 
     7035+ * runs with interrupts turned off.  People who may want to modify 
     7036+ * rs_interrupt() should try to keep the interrupt handler as fast as 
     7037+ * possible.  After you are done making modifications, it is not a bad 
     7038+ * idea to do: 
     7039+ *  
     7040+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c 
     7041+ * 
     7042+ * and look at the resulting assemble code in serial.s. 
     7043+ * 
     7044+ *                             - Ted Ts'o (tytso@mit.edu), 7-Mar-93 
     7045+ * ----------------------------------------------------------------------- 
     7046+ */ 
     7047+ 
     7048+/* 
     7049+ * This routine is used by the interrupt handler to schedule 
     7050+ * processing in the software interrupt portion of the driver. 
     7051+ */ 
     7052+static _INLINE_ void rs_sched_event(struct async_struct *info, 
     7053+                                 int event) 
     7054+{ 
     7055+       info->event |= 1 << event; 
     7056+       queue_task(&info->tqueue, &tq_serial); 
     7057+       mark_bh(SERIAL_BH); 
     7058+} 
     7059+ 
     7060+static _INLINE_ void receive_chars(struct async_struct *info, 
     7061+                                int *status, struct pt_regs * regs) 
     7062+{ 
     7063+       struct tty_struct *tty = info->tty; 
     7064+       unsigned char ch; 
     7065+       struct  async_icount *icount; 
     7066+       int     max_count = 256; 
     7067+ 
     7068+       icount = &info->state->icount; 
     7069+       do { 
     7070+               if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 
     7071+                       tty->flip.tqueue.routine((void *) tty); 
     7072+                       if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 
     7073+                               /* no room in flip buffer, discard rx FIFO contents to clear IRQ 
     7074+                                * *FIXME* Hardware with auto flow control 
     7075+                                * would benefit from leaving the data in the FIFO and 
     7076+                                * disabling the rx IRQ until space becomes available. 
     7077+                                */ 
     7078+                               do { 
     7079+                                       serial_inp(info, UART_RX); 
     7080+                                       icount->overrun++; 
     7081+                                       *status = serial_inp(info, UART_LSR); 
     7082+                               } while ((*status & UART_LSR_DR) && (max_count-- > 0)); 
     7083+                               return;         // if TTY_DONT_FLIP is set 
     7084+                       } 
     7085+               } 
     7086+               ch = serial_inp(info, UART_RX); 
     7087+               *tty->flip.char_buf_ptr = ch; 
     7088+               icount->rx++; 
     7089+                
     7090+#ifdef SERIAL_DEBUG_INTR 
     7091+               printk("DR%02x:%02x...", ch, *status); 
     7092+#endif 
     7093+               *tty->flip.flag_buf_ptr = 0; 
     7094+               if (*status & (UART_LSR_BI | UART_LSR_PE | 
     7095+                              UART_LSR_FE | UART_LSR_OE)) { 
     7096+                       /* 
     7097+                        * For statistics only 
     7098+                        */ 
     7099+                       if (*status & UART_LSR_BI) { 
     7100+                               *status &= ~(UART_LSR_FE | UART_LSR_PE); 
     7101+                               icount->brk++; 
     7102+                               /* 
     7103+                                * We do the SysRQ and SAK checking 
     7104+                                * here because otherwise the break 
     7105+                                * may get masked by ignore_status_mask 
     7106+                                * or read_status_mask. 
     7107+                                */ 
     7108+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 
     7109+                               if (info->line == sercons.index) { 
     7110+                                       if (!break_pressed) { 
     7111+                                               break_pressed = jiffies; 
     7112+                                               goto ignore_char; 
     7113+                                       } 
     7114+                                       break_pressed = 0; 
     7115+                               } 
     7116+#endif 
     7117+                               if (info->flags & ASYNC_SAK) 
     7118+                                       do_SAK(tty); 
     7119+                       } else if (*status & UART_LSR_PE) 
     7120+                               icount->parity++; 
     7121+                       else if (*status & UART_LSR_FE) 
     7122+                               icount->frame++; 
     7123+                       if (*status & UART_LSR_OE) 
     7124+                               icount->overrun++; 
     7125+ 
     7126+                       /* 
     7127+                        * Mask off conditions which should be ignored. 
     7128+                        */ 
     7129+                       *status &= info->read_status_mask; 
     7130+ 
     7131+#ifdef CONFIG_SERIAL_CONSOLE 
     7132+                       if (info->line == sercons.index) { 
     7133+                               /* Recover the break flag from console xmit */ 
     7134+                               *status |= lsr_break_flag; 
     7135+                               lsr_break_flag = 0; 
     7136+                       } 
     7137+#endif 
     7138+                       if (*status & (UART_LSR_BI)) { 
     7139+#ifdef SERIAL_DEBUG_INTR 
     7140+                               printk("handling break...."); 
     7141+#endif 
     7142+                               *tty->flip.flag_buf_ptr = TTY_BREAK; 
     7143+                       } else if (*status & UART_LSR_PE) 
     7144+                               *tty->flip.flag_buf_ptr = TTY_PARITY; 
     7145+                       else if (*status & UART_LSR_FE) 
     7146+                               *tty->flip.flag_buf_ptr = TTY_FRAME; 
     7147+               } 
     7148+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 
     7149+               if (break_pressed && info->line == sercons.index) { 
     7150+                       if (ch != 0 && 
     7151+                           time_before(jiffies, break_pressed + HZ*5)) { 
     7152+                               handle_sysrq(ch, regs, NULL, NULL); 
     7153+                               break_pressed = 0; 
     7154+                               goto ignore_char; 
     7155+                       } 
     7156+                       break_pressed = 0; 
     7157+               } 
     7158+#endif 
     7159+               if ((*status & info->ignore_status_mask) == 0) { 
     7160+                       tty->flip.flag_buf_ptr++; 
     7161+                       tty->flip.char_buf_ptr++; 
     7162+                       tty->flip.count++; 
     7163+               } 
     7164+               if ((*status & UART_LSR_OE) && 
     7165+                   (tty->flip.count < TTY_FLIPBUF_SIZE)) { 
     7166+                       /* 
     7167+                        * Overrun is special, since it's reported 
     7168+                        * immediately, and doesn't affect the current 
     7169+                        * character 
     7170+                        */ 
     7171+                       *tty->flip.flag_buf_ptr = TTY_OVERRUN; 
     7172+                       tty->flip.count++; 
     7173+                       tty->flip.flag_buf_ptr++; 
     7174+                       tty->flip.char_buf_ptr++; 
     7175+               } 
     7176+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 
     7177+       ignore_char: 
     7178+#endif 
     7179+               *status = serial_inp(info, UART_LSR); 
     7180+       } while ((*status & UART_LSR_DR) && (max_count-- > 0)); 
     7181+#if (LINUX_VERSION_CODE > 131394) /* 2.1.66 */ 
     7182+       tty_flip_buffer_push(tty); 
     7183+#else 
     7184+       queue_task_irq_off(&tty->flip.tqueue, &tq_timer); 
     7185+#endif  
     7186+} 
     7187+ 
     7188+static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) 
     7189+{ 
     7190+       int count; 
     7191+ 
     7192+       if (info->x_char) { 
     7193+               serial_outp(info, UART_TX, info->x_char); 
     7194+               info->state->icount.tx++; 
     7195+               info->x_char = 0; 
     7196+               if (intr_done) 
     7197+                       *intr_done = 0; 
     7198+               return; 
     7199+       } 
     7200+       if (info->xmit.head == info->xmit.tail 
     7201+           || info->tty->stopped 
     7202+           || info->tty->hw_stopped) { 
     7203+               info->IER &= ~UART_IER_THRI; 
     7204+               serial_out(info, UART_IER, info->IER); 
     7205+               return; 
     7206+       } 
     7207+        
     7208+       count = info->xmit_fifo_size; 
     7209+       do { 
     7210+               serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]); 
     7211+               info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); 
     7212+               info->state->icount.tx++; 
     7213+               if (info->xmit.head == info->xmit.tail) 
     7214+                       break; 
     7215+       } while (--count > 0); 
     7216+        
     7217+       if (CIRC_CNT(info->xmit.head, 
     7218+                    info->xmit.tail, 
     7219+                    SERIAL_XMIT_SIZE) < WAKEUP_CHARS) 
     7220+               rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); 
     7221+ 
     7222+#ifdef SERIAL_DEBUG_INTR 
     7223+       printk("THRE..."); 
     7224+#endif 
     7225+       if (intr_done) 
     7226+               *intr_done = 0; 
     7227+ 
     7228+       if (info->xmit.head == info->xmit.tail) { 
     7229+               info->IER &= ~UART_IER_THRI; 
     7230+               serial_out(info, UART_IER, info->IER); 
     7231+       } 
     7232+} 
     7233+ 
     7234+static _INLINE_ void check_modem_status(struct async_struct *info) 
     7235+{ 
     7236+       int     status; 
     7237+       struct  async_icount *icount; 
     7238+        
     7239+       status = serial_in(info, UART_MSR); 
     7240+ 
     7241+       if (status & UART_MSR_ANY_DELTA) { 
     7242+               icount = &info->state->icount; 
     7243+               /* update input line counters */ 
     7244+               if (status & UART_MSR_TERI) 
     7245+                       icount->rng++; 
     7246+               if (status & UART_MSR_DDSR) 
     7247+                       icount->dsr++; 
     7248+               if (status & UART_MSR_DDCD) { 
     7249+                       icount->dcd++; 
     7250+#ifdef CONFIG_HARD_PPS 
     7251+                       if ((info->flags & ASYNC_HARDPPS_CD) && 
     7252+                           (status & UART_MSR_DCD)) 
     7253+                               hardpps(); 
     7254+#endif 
     7255+               } 
     7256+               if (status & UART_MSR_DCTS) 
     7257+                       icount->cts++; 
     7258+               wake_up_interruptible(&info->delta_msr_wait); 
     7259+       } 
     7260+ 
     7261+       if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { 
     7262+#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) 
     7263+               printk("ttys%d CD now %s...", info->line, 
     7264+                      (status & UART_MSR_DCD) ? "on" : "off"); 
     7265+#endif          
     7266+               if (status & UART_MSR_DCD) 
     7267+                       wake_up_interruptible(&info->open_wait); 
     7268+               else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && 
     7269+                          (info->flags & ASYNC_CALLOUT_NOHUP))) { 
     7270+#ifdef SERIAL_DEBUG_OPEN 
     7271+                       printk("doing serial hangup..."); 
     7272+#endif 
     7273+                       if (info->tty) 
     7274+                               tty_hangup(info->tty); 
     7275+               } 
     7276+       } 
     7277+       if (info->flags & ASYNC_CTS_FLOW) { 
     7278+               if (info->tty->hw_stopped) { 
     7279+                       if (status & UART_MSR_CTS) { 
     7280+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) 
     7281+                               printk("CTS tx start..."); 
     7282+#endif 
     7283+                               info->tty->hw_stopped = 0; 
     7284+                               info->IER |= UART_IER_THRI; 
     7285+                               serial_out(info, UART_IER, info->IER); 
     7286+                               rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); 
     7287+                               return; 
     7288+                       } 
     7289+               } else { 
     7290+                       if (!(status & UART_MSR_CTS)) { 
     7291+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) 
     7292+                               printk("CTS tx stop..."); 
     7293+#endif 
     7294+                               info->tty->hw_stopped = 1; 
     7295+                               info->IER &= ~UART_IER_THRI; 
     7296+                               serial_out(info, UART_IER, info->IER); 
     7297+                       } 
     7298+               } 
     7299+       } 
     7300+} 
     7301+ 
     7302+#ifdef CONFIG_SERIAL_SHARE_IRQ 
     7303+/* 
     7304+ * This is the serial driver's generic interrupt routine 
     7305+ */ 
     7306+static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) 
     7307+{ 
     7308+       int status, iir; 
     7309+       struct async_struct * info; 
     7310+       int pass_counter = 0; 
     7311+       struct async_struct *end_mark = 0; 
     7312+#ifdef CONFIG_SERIAL_MULTIPORT  
     7313+       int first_multi = 0; 
     7314+       struct rs_multiport_struct *multi; 
     7315+#endif 
     7316+ 
     7317+#ifdef SERIAL_DEBUG_INTR 
     7318+       printk("rs_interrupt(%d)...", irq); 
     7319+#endif 
     7320+ 
     7321+       info = IRQ_ports[irq]; 
     7322+       if (!info) 
     7323+               return; 
     7324+ 
     7325+#ifdef CONFIG_SERIAL_MULTIPORT  
     7326+       multi = &rs_multiport[irq]; 
     7327+       if (multi->port_monitor) 
     7328+               first_multi = inb(multi->port_monitor); 
     7329+#endif 
     7330+ 
     7331+       do { 
     7332+               if (!info->tty || 
     7333+                   ((iir=serial_in(info, UART_IIR)) & UART_IIR_NO_INT)) { 
     7334+                       if (!end_mark) 
     7335+                               end_mark = info; 
     7336+                       goto next; 
     7337+               } 
     7338+#ifdef SERIAL_DEBUG_INTR 
     7339+               printk("IIR = %x...", serial_in(info, UART_IIR)); 
     7340+#endif 
     7341+               end_mark = 0; 
     7342+ 
     7343+               info->last_active = jiffies; 
     7344+ 
     7345+               status = serial_inp(info, UART_LSR); 
     7346+#ifdef SERIAL_DEBUG_INTR 
     7347+               printk("status = %x...", status); 
     7348+#endif 
     7349+               if (status & UART_LSR_DR) 
     7350+                       receive_chars(info, &status, regs); 
     7351+               check_modem_status(info); 
     7352+#ifdef CONFIG_MELAN 
     7353+               if ((status & UART_LSR_THRE) || 
     7354+                       /* for buggy ELAN processors */ 
     7355+                       ((iir & UART_IIR_ID) == UART_IIR_THRI)) 
     7356+                       transmit_chars(info, 0); 
     7357+#else 
     7358+               if (status & UART_LSR_THRE) 
     7359+                       transmit_chars(info, 0); 
     7360+#endif 
     7361+ 
     7362+       next: 
     7363+               info = info->next_port; 
     7364+               if (!info) { 
     7365+                       info = IRQ_ports[irq]; 
     7366+                       if (pass_counter++ > RS_ISR_PASS_LIMIT) { 
     7367+#if 0 
     7368+                               printk("rs loop break\n"); 
     7369+#endif 
     7370+                               break;  /* Prevent infinite loops */ 
     7371+                       } 
     7372+                       continue; 
     7373+               } 
     7374+       } while (end_mark != info); 
     7375+#ifdef CONFIG_SERIAL_MULTIPORT  
     7376+       if (multi->port_monitor) 
     7377+               printk("rs port monitor (normal) irq %d: 0x%x, 0x%x\n", 
     7378+                      info->state->irq, first_multi, 
     7379+                      inb(multi->port_monitor)); 
     7380+#endif 
     7381+#ifdef SERIAL_DEBUG_INTR 
     7382+       printk("end.\n"); 
     7383+#endif 
     7384+} 
     7385+#endif /* #ifdef CONFIG_SERIAL_SHARE_IRQ */ 
     7386+ 
     7387+ 
     7388+/* 
     7389+ * This is the serial driver's interrupt routine for a single port 
     7390+ */ 
     7391+static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) 
     7392+{ 
     7393+       int status, iir; 
     7394+       int pass_counter = 0; 
     7395+       struct async_struct * info; 
     7396+#ifdef CONFIG_SERIAL_MULTIPORT  
     7397+       int first_multi = 0; 
     7398+       struct rs_multiport_struct *multi; 
     7399+#endif 
     7400+        
     7401+#ifdef SERIAL_DEBUG_INTR 
     7402+       printk("rs_interrupt_single(%d)...", irq); 
     7403+#endif 
     7404+ 
     7405+       info = IRQ_ports[irq]; 
     7406+       if (!info || !info->tty) 
     7407+               return; 
     7408+ 
     7409+#ifdef CONFIG_SERIAL_MULTIPORT  
     7410+       multi = &rs_multiport[irq]; 
     7411+       if (multi->port_monitor) 
     7412+               first_multi = inb(multi->port_monitor); 
     7413+#endif 
     7414+ 
     7415+       iir = serial_in(info, UART_IIR); 
     7416+       do { 
     7417+               status = serial_inp(info, UART_LSR); 
     7418+#ifdef SERIAL_DEBUG_INTR 
     7419+               printk("status = %x...", status); 
     7420+#endif 
     7421+               if (status & UART_LSR_DR) 
     7422+                       receive_chars(info, &status, regs); 
     7423+               check_modem_status(info); 
     7424+#ifdef CONFIG_MELAN 
     7425+               if ((status & UART_LSR_THRE) || 
     7426+                   /* For buggy ELAN processors */ 
     7427+                   ((iir & UART_IIR_ID) == UART_IIR_THRI)) 
     7428+                       transmit_chars(info, 0); 
     7429+#else 
     7430+               if (status & UART_LSR_THRE) 
     7431+                       transmit_chars(info, 0); 
     7432+#endif 
     7433+               if (pass_counter++ > RS_ISR_PASS_LIMIT) { 
     7434+#if SERIAL_DEBUG_INTR 
     7435+                       printk("rs_single loop break.\n"); 
     7436+#endif 
     7437+                       break; 
     7438+               } 
     7439+               iir = serial_in(info, UART_IIR); 
     7440+#ifdef SERIAL_DEBUG_INTR 
     7441+               printk("IIR = %x...", iir); 
     7442+#endif 
     7443+       } while ((iir & UART_IIR_NO_INT) == 0); 
     7444+       info->last_active = jiffies; 
     7445+#ifdef CONFIG_SERIAL_MULTIPORT  
     7446+       if (multi->port_monitor) 
     7447+               printk("rs port monitor (single) irq %d: 0x%x, 0x%x\n", 
     7448+                      info->state->irq, first_multi, 
     7449+                      inb(multi->port_monitor)); 
     7450+#endif 
     7451+#ifdef SERIAL_DEBUG_INTR 
     7452+       printk("end.\n"); 
     7453+#endif 
     7454+} 
     7455+ 
     7456+#ifdef CONFIG_SERIAL_MULTIPORT  
     7457+/* 
     7458+ * This is the serial driver's for multiport boards 
     7459+ */ 
     7460+static void rs_interrupt_multi(int irq, void *dev_id, struct pt_regs * regs) 
     7461+{ 
     7462+       int status; 
     7463+       struct async_struct * info; 
     7464+       int pass_counter = 0; 
     7465+       int first_multi= 0; 
     7466+       struct rs_multiport_struct *multi; 
     7467+ 
     7468+#ifdef SERIAL_DEBUG_INTR 
     7469+       printk("rs_interrupt_multi(%d)...", irq); 
     7470+#endif 
     7471+ 
     7472+       info = IRQ_ports[irq]; 
     7473+       if (!info) 
     7474+               return; 
     7475+       multi = &rs_multiport[irq]; 
     7476+       if (!multi->port1) { 
     7477+               /* Should never happen */ 
     7478+               printk("rs_interrupt_multi: NULL port1!\n"); 
     7479+               return; 
     7480+       } 
     7481+       if (multi->port_monitor) 
     7482+               first_multi = inb(multi->port_monitor); 
     7483+        
     7484+       while (1) { 
     7485+               if (!info->tty || 
     7486+                   (serial_in(info, UART_IIR) & UART_IIR_NO_INT)) 
     7487+                       goto next; 
     7488+ 
     7489+               info->last_active = jiffies; 
     7490+ 
     7491+               status = serial_inp(info, UART_LSR); 
     7492+#ifdef SERIAL_DEBUG_INTR 
     7493+               printk("status = %x...", status); 
     7494+#endif 
     7495+               if (status & UART_LSR_DR) 
     7496+                       receive_chars(info, &status, regs); 
     7497+               check_modem_status(info); 
     7498+               if (status & UART_LSR_THRE) 
     7499+                       transmit_chars(info, 0); 
     7500+ 
     7501+       next: 
     7502+               info = info->next_port; 
     7503+               if (info) 
     7504+                       continue; 
     7505+ 
     7506+               info = IRQ_ports[irq]; 
     7507+               /* 
     7508+                * The user was a bonehead, and misconfigured their 
     7509+                * multiport info.  Rather than lock up the kernel 
     7510+                * in an infinite loop, if we loop too many times, 
     7511+                * print a message and break out of the loop. 
     7512+                */ 
     7513+               if (pass_counter++ > RS_ISR_PASS_LIMIT) { 
     7514+                       printk("Misconfigured multiport serial info " 
     7515+                              "for irq %d.  Breaking out irq loop\n", irq); 
     7516+                       break;  
     7517+               } 
     7518+               if (multi->port_monitor) 
     7519+                       printk("rs port monitor irq %d: 0x%x, 0x%x\n", 
     7520+                              info->state->irq, first_multi, 
     7521+                              inb(multi->port_monitor)); 
     7522+               if ((inb(multi->port1) & multi->mask1) != multi->match1) 
     7523+                       continue; 
     7524+               if (!multi->port2) 
     7525+                       break; 
     7526+               if ((inb(multi->port2) & multi->mask2) != multi->match2) 
     7527+                       continue; 
     7528+               if (!multi->port3) 
     7529+                       break; 
     7530+               if ((inb(multi->port3) & multi->mask3) != multi->match3) 
     7531+                       continue; 
     7532+               if (!multi->port4) 
     7533+                       break; 
     7534+               if ((inb(multi->port4) & multi->mask4) != multi->match4) 
     7535+                       continue; 
     7536+               break; 
     7537+       }  
     7538+#ifdef SERIAL_DEBUG_INTR 
     7539+       printk("end.\n"); 
     7540+#endif 
     7541+} 
     7542+#endif 
     7543+ 
     7544+/* 
     7545+ * ------------------------------------------------------------------- 
     7546+ * Here ends the serial interrupt routines. 
     7547+ * ------------------------------------------------------------------- 
     7548+ */ 
     7549+ 
     7550+/* 
     7551+ * This routine is used to handle the "bottom half" processing for the 
     7552+ * serial driver, known also the "software interrupt" processing. 
     7553+ * This processing is done at the kernel interrupt level, after the 
     7554+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This 
     7555+ * is where time-consuming activities which can not be done in the 
     7556+ * interrupt driver proper are done; the interrupt driver schedules 
     7557+ * them using rs_sched_event(), and they get done here. 
     7558+ */ 
     7559+static void do_serial_bh(void) 
     7560+{ 
     7561+       run_task_queue(&tq_serial); 
     7562+} 
     7563+ 
     7564+static void do_softint(void *private_) 
     7565+{ 
     7566+       struct async_struct     *info = (struct async_struct *) private_; 
     7567+       struct tty_struct       *tty; 
     7568+ 
     7569+       tty = info->tty; 
     7570+       if (!tty) 
     7571+               return; 
     7572+ 
     7573+       if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { 
     7574+               tty_wakeup(tty); 
     7575+                
     7576+#ifdef SERIAL_HAVE_POLL_WAIT 
     7577+               wake_up_interruptible(&tty->poll_wait); 
     7578+#endif 
     7579+       } 
     7580+} 
     7581+ 
     7582+/* 
     7583+ * This subroutine is called when the RS_TIMER goes off.  It is used 
     7584+ * by the serial driver to handle ports that do not have an interrupt 
     7585+ * (irq=0).  This doesn't work very well for 16450's, but gives barely 
     7586+ * passable results for a 16550A.  (Although at the expense of much 
     7587+ * CPU overhead). 
     7588+ */ 
     7589+static void rs_timer(unsigned long dummy) 
     7590+{ 
     7591+       static unsigned long last_strobe; 
     7592+       struct async_struct *info; 
     7593+       unsigned int    i; 
     7594+       unsigned long flags; 
     7595+ 
     7596+       if ((jiffies - last_strobe) >= RS_STROBE_TIME) { 
     7597+               for (i=0; i < NR_IRQS; i++) { 
     7598+                       info = IRQ_ports[i]; 
     7599+                       if (!info) 
     7600+                               continue; 
     7601+                       save_flags(flags); cli(); 
     7602+#ifdef CONFIG_SERIAL_SHARE_IRQ 
     7603+                       if (info->next_port) { 
     7604+                               do { 
     7605+                                       serial_out(info, UART_IER, 0); 
     7606+                                       info->IER |= UART_IER_THRI; 
     7607+                                       serial_out(info, UART_IER, info->IER); 
     7608+                                       info = info->next_port; 
     7609+                               } while (info); 
     7610+#ifdef CONFIG_SERIAL_MULTIPORT 
     7611+                               if (rs_multiport[i].port1) 
     7612+                                       rs_interrupt_multi(i, NULL, NULL); 
     7613+                               else 
     7614+#endif 
     7615+                                       rs_interrupt(i, NULL, NULL); 
     7616+                       } else 
     7617+#endif /* CONFIG_SERIAL_SHARE_IRQ */ 
     7618+                               rs_interrupt_single(i, NULL, NULL); 
     7619+                       restore_flags(flags); 
     7620+               } 
     7621+       } 
     7622+       last_strobe = jiffies; 
     7623+       mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); 
     7624+ 
     7625+       if (IRQ_ports[0]) { 
     7626+               save_flags(flags); cli(); 
     7627+#ifdef CONFIG_SERIAL_SHARE_IRQ 
     7628+               rs_interrupt(0, NULL, NULL); 
     7629+#else 
     7630+               rs_interrupt_single(0, NULL, NULL); 
     7631+#endif 
     7632+               restore_flags(flags); 
     7633+ 
     7634+               mod_timer(&serial_timer, jiffies + IRQ_timeout[0]); 
     7635+       } 
     7636+} 
     7637+ 
     7638+/* 
     7639+ * --------------------------------------------------------------- 
     7640+ * Low level utility subroutines for the serial driver:  routines to 
     7641+ * figure out the appropriate timeout for an interrupt chain, routines 
     7642+ * to initialize and startup a serial port, and routines to shutdown a 
     7643+ * serial port.  Useful stuff like that. 
     7644+ * --------------------------------------------------------------- 
     7645+ */ 
     7646+ 
     7647+/* 
     7648+ * This routine figures out the correct timeout for a particular IRQ. 
     7649+ * It uses the smallest timeout of all of the serial ports in a 
     7650+ * particular interrupt chain.  Now only used for IRQ 0.... 
     7651+ */ 
     7652+static void figure_IRQ_timeout(int irq) 
     7653+{ 
     7654+       struct  async_struct    *info; 
     7655+       int     timeout = 60*HZ;        /* 60 seconds === a long time :-) */ 
     7656+ 
     7657+       info = IRQ_ports[irq]; 
     7658+       if (!info) { 
     7659+               IRQ_timeout[irq] = 60*HZ; 
     7660+               return; 
     7661+       } 
     7662+       while (info) { 
     7663+               if (info->timeout < timeout) 
     7664+                       timeout = info->timeout; 
     7665+               info = info->next_port; 
     7666+       } 
     7667+       if (!irq) 
     7668+               timeout = timeout / 2; 
     7669+       IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1; 
     7670+} 
     7671+ 
     7672+#ifdef CONFIG_SERIAL_RSA 
     7673+/* Attempts to turn on the RSA FIFO.  Returns zero on failure */ 
     7674+static int enable_rsa(struct async_struct *info) 
     7675+{ 
     7676+       unsigned char mode; 
     7677+       int result; 
     7678+       unsigned long flags; 
     7679+ 
     7680+       save_flags(flags); cli(); 
     7681+       mode = serial_inp(info, UART_RSA_MSR); 
     7682+       result = mode & UART_RSA_MSR_FIFO; 
     7683+ 
     7684+       if (!result) { 
     7685+               serial_outp(info, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); 
     7686+               mode = serial_inp(info, UART_RSA_MSR); 
     7687+               result = mode & UART_RSA_MSR_FIFO; 
     7688+       } 
     7689+ 
     7690+       restore_flags(flags); 
     7691+       return result; 
     7692+} 
     7693+ 
     7694+/* Attempts to turn off the RSA FIFO.  Returns zero on failure */ 
     7695+static int disable_rsa(struct async_struct *info) 
     7696+{ 
     7697+       unsigned char mode; 
     7698+       int result; 
     7699+       unsigned long flags; 
     7700+ 
     7701+       save_flags(flags); cli(); 
     7702+       mode = serial_inp(info, UART_RSA_MSR); 
     7703+       result = !(mode & UART_RSA_MSR_FIFO); 
     7704+ 
     7705+       if (!result) { 
     7706+               serial_outp(info, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); 
     7707+               mode = serial_inp(info, UART_RSA_MSR); 
     7708+               result = !(mode & UART_RSA_MSR_FIFO); 
     7709+       } 
     7710+ 
     7711+       restore_flags(flags); 
     7712+       return result; 
     7713+} 
     7714+#endif /* CONFIG_SERIAL_RSA */ 
     7715+ 
     7716+static int startup(struct async_struct * info) 
     7717+{ 
     7718+       unsigned long flags; 
     7719+       int     retval=0; 
     7720+       void (*handler)(int, void *, struct pt_regs *); 
     7721+       struct serial_state *state= info->state; 
     7722+       unsigned long page; 
     7723+#ifdef CONFIG_SERIAL_MANY_PORTS 
     7724+       unsigned short ICP; 
     7725+#endif 
     7726+ 
     7727+       page = get_zeroed_page(GFP_KERNEL); 
     7728+       if (!page) 
     7729+               return -ENOMEM; 
     7730+ 
     7731+       save_flags(flags); cli(); 
     7732+ 
     7733+       if (info->flags & ASYNC_INITIALIZED) { 
     7734+               free_page(page); 
     7735+               goto errout; 
     7736+       } 
     7737+ 
     7738+       if (!CONFIGURED_SERIAL_PORT(state) || !state->type) { 
     7739+               if (info->tty) 
     7740+                       set_bit(TTY_IO_ERROR, &info->tty->flags); 
     7741+               free_page(page); 
     7742+               goto errout; 
     7743+       } 
     7744+       if (info->xmit.buf) 
     7745+               free_page(page); 
     7746+       else 
     7747+               info->xmit.buf = (unsigned char *) page; 
     7748+ 
     7749+#ifdef SERIAL_DEBUG_OPEN 
     7750+       printk("starting up ttys%d (irq %d)...", info->line, state->irq); 
     7751+#endif 
     7752+ 
     7753+       if (uart_config[state->type].flags & UART_STARTECH) { 
     7754+               /* Wake up UART */ 
     7755+               serial_outp(info, UART_LCR, 0xBF); 
     7756+               serial_outp(info, UART_EFR, UART_EFR_ECB); 
     7757+               /* 
     7758+                * Turn off LCR == 0xBF so we actually set the IER 
     7759+                * register on the XR16C850 
     7760+                */ 
     7761+               serial_outp(info, UART_LCR, 0); 
     7762+               serial_outp(info, UART_IER, 0); 
     7763+               /* 
     7764+                * Now reset LCR so we can turn off the ECB bit 
     7765+                */ 
     7766+               serial_outp(info, UART_LCR, 0xBF); 
     7767+               serial_outp(info, UART_EFR, 0); 
     7768+               /* 
     7769+                * For a XR16C850, we need to set the trigger levels 
     7770+                */ 
     7771+               if (state->type == PORT_16850) { 
     7772+                       serial_outp(info, UART_FCTR, UART_FCTR_TRGD | 
     7773+                                       UART_FCTR_RX); 
     7774+                       serial_outp(info, UART_TRG, UART_TRG_96); 
     7775+                       serial_outp(info, UART_FCTR, UART_FCTR_TRGD | 
     7776+                                       UART_FCTR_TX); 
     7777+                       serial_outp(info, UART_TRG, UART_TRG_96); 
     7778+               } 
     7779+               serial_outp(info, UART_LCR, 0); 
     7780+       } 
     7781+ 
     7782+       if (state->type == PORT_16750) { 
     7783+               /* Wake up UART */ 
     7784+               serial_outp(info, UART_IER, 0); 
     7785+       } 
     7786+ 
     7787+       if (state->type == PORT_16C950) { 
     7788+               /* Wake up and initialize UART */ 
     7789+               info->ACR = 0; 
     7790+               serial_outp(info, UART_LCR, 0xBF); 
     7791+               serial_outp(info, UART_EFR, UART_EFR_ECB); 
     7792+               serial_outp(info, UART_IER, 0); 
     7793+               serial_outp(info, UART_LCR, 0); 
     7794+               serial_icr_write(info, UART_CSR, 0); /* Reset the UART */ 
     7795+               serial_outp(info, UART_LCR, 0xBF); 
     7796+               serial_outp(info, UART_EFR, UART_EFR_ECB); 
     7797+               serial_outp(info, UART_LCR, 0); 
     7798+       } 
     7799+ 
     7800+#ifdef CONFIG_SERIAL_RSA 
     7801+       /* 
     7802+        * If this is an RSA port, see if we can kick it up to the 
     7803+        * higher speed clock. 
     7804+        */ 
     7805+       if (state->type == PORT_RSA) { 
     7806+               if (state->baud_base != SERIAL_RSA_BAUD_BASE && 
     7807+                   enable_rsa(info)) 
     7808+                       state->baud_base = SERIAL_RSA_BAUD_BASE; 
     7809+               if (state->baud_base == SERIAL_RSA_BAUD_BASE) 
     7810+                       serial_outp(info, UART_RSA_FRR, 0); 
     7811+       } 
     7812+#endif 
     7813+ 
     7814+       /* 
     7815+        * Clear the FIFO buffers and disable them 
     7816+        * (they will be reenabled in change_speed()) 
     7817+        */ 
     7818+       if (uart_config[state->type].flags & UART_CLEAR_FIFO) { 
     7819+               serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); 
     7820+               serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | 
     7821+                                            UART_FCR_CLEAR_RCVR | 
     7822+                                            UART_FCR_CLEAR_XMIT)); 
     7823+               serial_outp(info, UART_FCR, 0); 
     7824+       } 
     7825+ 
     7826+       /* 
     7827+        * Clear the interrupt registers. 
     7828+        */ 
     7829+       (void) serial_inp(info, UART_LSR); 
     7830+       (void) serial_inp(info, UART_RX); 
     7831+       (void) serial_inp(info, UART_IIR); 
     7832+       (void) serial_inp(info, UART_MSR); 
     7833+ 
     7834+       /* 
     7835+        * At this point there's no way the LSR could still be 0xFF; 
     7836+        * if it is, then bail out, because there's likely no UART 
     7837+        * here. 
     7838+        */ 
     7839+       if (!(info->flags & ASYNC_BUGGY_UART) && 
     7840+           (serial_inp(info, UART_LSR) == 0xff)) { 
     7841+               printk("ttyS%d: LSR safety check engaged!\n", state->line); 
     7842+               if (capable(CAP_SYS_ADMIN)) { 
     7843+                       if (info->tty) 
     7844+                               set_bit(TTY_IO_ERROR, &info->tty->flags); 
     7845+               } else 
     7846+                       retval = -ENODEV; 
     7847+               goto errout; 
     7848+       } 
     7849+        
     7850+       /* 
     7851+        * Allocate the IRQ if necessary 
     7852+        */ 
     7853+       if (state->irq && (!IRQ_ports[state->irq] || 
     7854+                         !IRQ_ports[state->irq]->next_port)) { 
     7855+               if (IRQ_ports[state->irq]) { 
     7856+#ifdef CONFIG_SERIAL_SHARE_IRQ 
     7857+                       free_irq(state->irq, &IRQ_ports[state->irq]); 
     7858+#ifdef CONFIG_SERIAL_MULTIPORT                          
     7859+                       if (rs_multiport[state->irq].port1) 
     7860+                               handler = rs_interrupt_multi; 
     7861+                       else 
     7862+#endif 
     7863+                               handler = rs_interrupt; 
     7864+#else 
     7865+                       retval = -EBUSY; 
     7866+                       goto errout; 
     7867+#endif /* CONFIG_SERIAL_SHARE_IRQ */ 
     7868+               } else  
     7869+                       handler = rs_interrupt_single; 
     7870+ 
     7871+               retval = request_irq(state->irq, handler, SA_SHIRQ, 
     7872+                                    "serial", &IRQ_ports[state->irq]); 
     7873+               if (retval) { 
     7874+                       if (capable(CAP_SYS_ADMIN)) { 
     7875+                               if (info->tty) 
     7876+                                       set_bit(TTY_IO_ERROR, 
     7877+                                               &info->tty->flags); 
     7878+                               retval = 0; 
     7879+                       } 
     7880+                       goto errout; 
     7881+               } 
     7882+       } 
     7883+ 
     7884+       /* 
     7885+        * Insert serial port into IRQ chain. 
     7886+        */ 
     7887+       info->prev_port = 0; 
     7888+       info->next_port = IRQ_ports[state->irq]; 
     7889+       if (info->next_port) 
     7890+               info->next_port->prev_port = info; 
     7891+       IRQ_ports[state->irq] = info; 
     7892+       figure_IRQ_timeout(state->irq); 
     7893+ 
     7894+       /* 
     7895+        * Now, initialize the UART  
     7896+        */ 
     7897+       serial_outp(info, UART_LCR, UART_LCR_WLEN8);    /* reset DLAB */ 
     7898+ 
     7899+       info->MCR = 0; 
     7900+       if (info->tty->termios->c_cflag & CBAUD) 
     7901+               info->MCR = UART_MCR_DTR | UART_MCR_RTS; 
     7902+#ifdef CONFIG_SERIAL_MANY_PORTS 
     7903+       if (info->flags & ASYNC_FOURPORT) { 
     7904+               if (state->irq == 0) 
     7905+                       info->MCR |= UART_MCR_OUT1; 
     7906+       } else 
     7907+#endif 
     7908+       { 
     7909+               if (state->irq != 0) 
     7910+                       info->MCR |= UART_MCR_OUT2; 
     7911+       } 
     7912+       info->MCR |= ALPHA_KLUDGE_MCR;          /* Don't ask */ 
     7913+       serial_outp(info, UART_MCR, info->MCR); 
     7914+        
     7915+       /* 
     7916+        * Finally, enable interrupts 
     7917+        */ 
     7918+       info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; 
     7919+       serial_outp(info, UART_IER, info->IER); /* enable interrupts */ 
     7920+        
     7921+#ifdef CONFIG_SERIAL_MANY_PORTS 
     7922+       if (info->flags & ASYNC_FOURPORT) { 
     7923+               /* Enable interrupts on the AST Fourport board */ 
     7924+               ICP = (info->port & 0xFE0) | 0x01F; 
     7925+               outb_p(0x80, ICP); 
     7926+               (void) inb_p(ICP); 
     7927+       } 
     7928+#endif 
     7929+ 
     7930+       /* 
     7931+        * And clear the interrupt registers again for luck. 
     7932+        */ 
     7933+       (void)serial_inp(info, UART_LSR); 
     7934+       (void)serial_inp(info, UART_RX); 
     7935+       (void)serial_inp(info, UART_IIR); 
     7936+       (void)serial_inp(info, UART_MSR); 
     7937+ 
     7938+       if (info->tty) 
     7939+               clear_bit(TTY_IO_ERROR, &info->tty->flags); 
     7940+       info->xmit.head = info->xmit.tail = 0; 
     7941+ 
     7942+       /* 
     7943+        * Set up serial timers... 
     7944+        */ 
     7945+       mod_timer(&serial_timer, jiffies + 2*HZ/100); 
     7946+ 
     7947+       /* 
     7948+        * Set up the tty->alt_speed kludge 
     7949+        */ 
     7950+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */ 
     7951+       if (info->tty) { 
     7952+               if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 
     7953+                       info->tty->alt_speed = 57600; 
     7954+               if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 
     7955+                       info->tty->alt_speed = 115200; 
     7956+               if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 
     7957+                       info->tty->alt_speed = 230400; 
     7958+               if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 
     7959+                       info->tty->alt_speed = 460800; 
     7960+       } 
     7961+#endif 
     7962+        
     7963+       /* 
     7964+        * and set the speed of the serial port 
     7965+        */ 
     7966+       change_speed(info, 0); 
     7967+ 
     7968+       info->flags |= ASYNC_INITIALIZED; 
     7969+       restore_flags(flags); 
     7970+       return 0; 
     7971+        
     7972+errout: 
     7973+       restore_flags(flags); 
     7974+       return retval; 
     7975+} 
     7976+ 
     7977+/* 
     7978+ * This routine will shutdown a serial port; interrupts are disabled, and 
     7979+ * DTR is dropped if the hangup on close termio flag is on. 
     7980+ */ 
     7981+static void shutdown(struct async_struct * info) 
     7982+{ 
     7983+       unsigned long   flags; 
     7984+       struct serial_state *state; 
     7985+       int             retval; 
     7986+ 
     7987+       if (!(info->flags & ASYNC_INITIALIZED)) 
     7988+               return; 
     7989+ 
     7990+       state = info->state; 
     7991+ 
     7992+#ifdef SERIAL_DEBUG_OPEN 
     7993+       printk("Shutting down serial port %d (irq %d)....", info->line, 
     7994+              state->irq); 
     7995+#endif 
     7996+        
     7997+       save_flags(flags); cli(); /* Disable interrupts */ 
     7998+ 
     7999+       /* 
     8000+        * clear delta_msr_wait queue to avoid mem leaks: we may free the irq 
     8001+        * here so the queue might never be waken up 
     8002+        */ 
     8003+       wake_up_interruptible(&info->delta_msr_wait); 
     8004+        
     8005+       /* 
     8006+        * First unlink the serial port from the IRQ chain... 
     8007+        */ 
     8008+       if (info->next_port) 
     8009+               info->next_port->prev_port = info->prev_port; 
     8010+       if (info->prev_port) 
     8011+               info->prev_port->next_port = info->next_port; 
     8012+       else 
     8013+               IRQ_ports[state->irq] = info->next_port; 
     8014+       figure_IRQ_timeout(state->irq); 
     8015+        
     8016+       /* 
     8017+        * Free the IRQ, if necessary 
     8018+        */ 
     8019+       if (state->irq && (!IRQ_ports[state->irq] || 
     8020+                         !IRQ_ports[state->irq]->next_port)) { 
     8021+               if (IRQ_ports[state->irq]) { 
     8022+                       free_irq(state->irq, &IRQ_ports[state->irq]); 
     8023+                       retval = request_irq(state->irq, rs_interrupt_single, 
     8024+                                            SA_SHIRQ, "serial", 
     8025+                                            &IRQ_ports[state->irq]); 
     8026+                        
     8027+                       if (retval) 
     8028+                               printk("serial shutdown: request_irq: error %d" 
     8029+                                      "  Couldn't reacquire IRQ.\n", retval); 
     8030+               } else 
     8031+                       free_irq(state->irq, &IRQ_ports[state->irq]); 
     8032+       } 
     8033+ 
     8034+       if (info->xmit.buf) { 
     8035+               unsigned long pg = (unsigned long) info->xmit.buf; 
     8036+               info->xmit.buf = 0; 
     8037+               free_page(pg); 
     8038+       } 
     8039+ 
     8040+       info->IER = 0; 
     8041+       serial_outp(info, UART_IER, 0x00);      /* disable all intrs */ 
     8042+#ifdef CONFIG_SERIAL_MANY_PORTS 
     8043+       if (info->flags & ASYNC_FOURPORT) { 
     8044+               /* reset interrupts on the AST Fourport board */ 
     8045+               (void) inb((info->port & 0xFE0) | 0x01F); 
     8046+               info->MCR |= UART_MCR_OUT1; 
     8047+       } else 
     8048+#endif 
     8049+               info->MCR &= ~UART_MCR_OUT2; 
     8050+       info->MCR |= ALPHA_KLUDGE_MCR;          /* Don't ask */ 
     8051+        
     8052+       /* disable break condition */ 
     8053+       serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC); 
     8054+        
     8055+       if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) 
     8056+               info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); 
     8057+       serial_outp(info, UART_MCR, info->MCR); 
     8058+ 
     8059+       /* disable FIFO's */     
     8060+       serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | 
     8061+                                    UART_FCR_CLEAR_RCVR | 
     8062+                                    UART_FCR_CLEAR_XMIT)); 
     8063+       serial_outp(info, UART_FCR, 0); 
     8064+ 
     8065+#ifdef CONFIG_SERIAL_RSA 
     8066+       /* 
     8067+        * Reset the RSA board back to 115kbps compat mode. 
     8068+        */ 
     8069+       if ((state->type == PORT_RSA) && 
     8070+           (state->baud_base == SERIAL_RSA_BAUD_BASE && 
     8071+            disable_rsa(info))) 
     8072+               state->baud_base = SERIAL_RSA_BAUD_BASE_LO; 
     8073+#endif 
     8074+        
     8075+ 
     8076+       (void)serial_in(info, UART_RX);    /* read data port to reset things */ 
     8077+        
     8078+       if (info->tty) 
     8079+               set_bit(TTY_IO_ERROR, &info->tty->flags); 
     8080+ 
     8081+       if (uart_config[info->state->type].flags & UART_STARTECH) { 
     8082+               /* Arrange to enter sleep mode */ 
     8083+               serial_outp(info, UART_LCR, 0xBF); 
     8084+               serial_outp(info, UART_EFR, UART_EFR_ECB); 
     8085+               serial_outp(info, UART_LCR, 0); 
     8086+               serial_outp(info, UART_IER, UART_IERX_SLEEP); 
     8087+               serial_outp(info, UART_LCR, 0xBF); 
     8088+               serial_outp(info, UART_EFR, 0); 
     8089+               serial_outp(info, UART_LCR, 0); 
     8090+       } 
     8091+       if (info->state->type == PORT_16750) { 
     8092+               /* Arrange to enter sleep mode */ 
     8093+               serial_outp(info, UART_IER, UART_IERX_SLEEP); 
     8094+       } 
     8095+       info->flags &= ~ASYNC_INITIALIZED; 
     8096+       restore_flags(flags); 
     8097+} 
     8098+ 
     8099+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ 
     8100+static int baud_table[] = { 
     8101+       0, 50, 75, 110, 134, 150, 200, 300, 
     8102+       600, 1200, 1800, 2400, 4800, 9600, 19200, 
     8103+       38400, 57600, 115200, 230400, 460800, 0 }; 
     8104+ 
     8105+static int tty_get_baud_rate(struct tty_struct *tty) 
     8106+{ 
     8107+       struct async_struct * info = (struct async_struct *)tty->driver_data; 
     8108+       unsigned int cflag, i; 
     8109+ 
     8110+       cflag = tty->termios->c_cflag; 
     8111+ 
     8112+       i = cflag & CBAUD; 
     8113+       if (i & CBAUDEX) { 
     8114+               i &= ~CBAUDEX; 
     8115+               if (i < 1 || i > 2)  
     8116+                       tty->termios->c_cflag &= ~CBAUDEX; 
     8117+               else 
     8118+                       i += 15; 
     8119+       } 
     8120+       if (i == 15) { 
     8121+               if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 
     8122+                       i += 1; 
     8123+               if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 
     8124+                       i += 2; 
     8125+       } 
     8126+       return baud_table[i]; 
     8127+} 
     8128+#endif 
     8129+ 
     8130+/* 
     8131+ * This routine is called to set the UART divisor registers to match 
     8132+ * the specified baud rate for a serial port. 
     8133+ */ 
     8134+static void change_speed(struct async_struct *info, 
     8135+                        struct termios *old_termios) 
     8136+{ 
     8137+       int     quot = 0, baud_base, baud; 
     8138+       unsigned cflag, cval, fcr = 0; 
     8139+       int     bits; 
     8140+       unsigned long   flags; 
     8141+ 
     8142+       if (!info->tty || !info->tty->termios) 
     8143+               return; 
     8144+       cflag = info->tty->termios->c_cflag; 
     8145+       if (!CONFIGURED_SERIAL_PORT(info)) 
     8146+               return; 
     8147+ 
     8148+       /* byte size and parity */ 
     8149+       switch (cflag & CSIZE) { 
     8150+             case CS5: cval = 0x00; bits = 7; break; 
     8151+             case CS6: cval = 0x01; bits = 8; break; 
     8152+             case CS7: cval = 0x02; bits = 9; break; 
     8153+             case CS8: cval = 0x03; bits = 10; break; 
     8154+             /* Never happens, but GCC is too dumb to figure it out */ 
     8155+             default:  cval = 0x00; bits = 7; break; 
     8156+             } 
     8157+       if (cflag & CSTOPB) { 
     8158+               cval |= 0x04; 
     8159+               bits++; 
     8160+       } 
     8161+       if (cflag & PARENB) { 
     8162+               cval |= UART_LCR_PARITY; 
     8163+               bits++; 
     8164+       } 
     8165+       if (!(cflag & PARODD)) 
     8166+               cval |= UART_LCR_EPAR; 
     8167+#ifdef CMSPAR 
     8168+       if (cflag & CMSPAR) 
     8169+               cval |= UART_LCR_SPAR; 
     8170+#endif 
     8171+ 
     8172+       /* Determine divisor based on baud rate */ 
     8173+       baud = tty_get_baud_rate(info->tty); 
     8174+       if (!baud) 
     8175+               baud = 9600;    /* B0 transition handled in rs_set_termios */ 
     8176+#ifdef CONFIG_SERIAL_RSA 
     8177+       if ((info->state->type == PORT_RSA) && 
     8178+           (info->state->baud_base != SERIAL_RSA_BAUD_BASE) && 
     8179+           enable_rsa(info)) 
     8180+               info->state->baud_base = SERIAL_RSA_BAUD_BASE; 
     8181+#endif 
     8182+       baud_base = info->state->baud_base; 
     8183+       if (info->state->type == PORT_16C950) { 
     8184+               if (baud <= baud_base) 
     8185+                       serial_icr_write(info, UART_TCR, 0); 
     8186+               else if (baud <= 2*baud_base) { 
     8187+                       serial_icr_write(info, UART_TCR, 0x8); 
     8188+                       baud_base = baud_base * 2; 
     8189+               } else if (baud <= 4*baud_base) { 
     8190+                       serial_icr_write(info, UART_TCR, 0x4); 
     8191+                       baud_base = baud_base * 4; 
     8192+               } else 
     8193+                       serial_icr_write(info, UART_TCR, 0); 
     8194+       } 
     8195+       if (baud == 38400 && 
     8196+           ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) 
     8197+               quot = info->state->custom_divisor; 
     8198+       else { 
     8199+               if (baud == 134) 
     8200+                       /* Special case since 134 is really 134.5 */ 
     8201+                       quot = (2*baud_base / 269); 
     8202+               else if (baud) 
     8203+                       quot = baud_base / baud; 
     8204+       } 
     8205+       /* If the quotient is zero refuse the change */ 
     8206+       if (!quot && old_termios) { 
     8207+               info->tty->termios->c_cflag &= ~CBAUD; 
     8208+               info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); 
     8209+               baud = tty_get_baud_rate(info->tty); 
     8210+               if (!baud) 
     8211+                       baud = 9600; 
     8212+               if (baud == 38400 && 
     8213+                   ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) 
     8214+                       quot = info->state->custom_divisor; 
     8215+               else { 
     8216+                       if (baud == 134) 
     8217+                               /* Special case since 134 is really 134.5 */ 
     8218+                               quot = (2*baud_base / 269); 
     8219+                       else if (baud) 
     8220+                               quot = baud_base / baud; 
     8221+               } 
     8222+       } 
     8223+       /* As a last resort, if the quotient is zero, default to 9600 bps */ 
     8224+       if (!quot) 
     8225+               quot = baud_base / 9600; 
     8226+       /* 
     8227+        * Work around a bug in the Oxford Semiconductor 952 rev B 
     8228+        * chip which causes it to seriously miscalculate baud rates 
     8229+        * when DLL is 0. 
     8230+        */ 
     8231+       if (((quot & 0xFF) == 0) && (info->state->type == PORT_16C950) && 
     8232+           (info->state->revision == 0x5201)) 
     8233+               quot++; 
     8234+        
     8235+       info->quot = quot; 
     8236+       info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); 
     8237+       info->timeout += HZ/50;         /* Add .02 seconds of slop */ 
     8238+ 
     8239+       /* Set up FIFO's */ 
     8240+       if (uart_config[info->state->type].flags & UART_USE_FIFO) { 
     8241+               if ((info->state->baud_base / quot) < 2400) 
     8242+                       fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; 
     8243+#ifdef CONFIG_SERIAL_RSA 
     8244+               else if (info->state->type == PORT_RSA) 
     8245+                       fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14; 
     8246+#endif 
     8247+               else 
     8248+                       fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8; 
     8249+       } 
     8250+       if (info->state->type == PORT_16750) 
     8251+               fcr |= UART_FCR7_64BYTE; 
     8252+        
     8253+       /* CTS flow control flag and modem status interrupts */ 
     8254+       info->IER &= ~UART_IER_MSI; 
     8255+       if (info->flags & ASYNC_HARDPPS_CD) 
     8256+               info->IER |= UART_IER_MSI; 
     8257+       if (cflag & CRTSCTS) { 
     8258+               info->flags |= ASYNC_CTS_FLOW; 
     8259+               info->IER |= UART_IER_MSI; 
     8260+       } else 
     8261+               info->flags &= ~ASYNC_CTS_FLOW; 
     8262+       if (cflag & CLOCAL) 
     8263+               info->flags &= ~ASYNC_CHECK_CD; 
     8264+       else { 
     8265+               info->flags |= ASYNC_CHECK_CD; 
     8266+               info->IER |= UART_IER_MSI; 
     8267+       } 
     8268+       serial_out(info, UART_IER, info->IER); 
     8269+ 
     8270+       /* 
     8271+        * Set up parity check flag 
     8272+        */ 
     8273+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) 
     8274+ 
     8275+       info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; 
     8276+       if (I_INPCK(info->tty)) 
     8277+               info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; 
     8278+       if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) 
     8279+               info->read_status_mask |= UART_LSR_BI; 
     8280+        
     8281+       /* 
     8282+        * Characters to ignore 
     8283+        */ 
     8284+       info->ignore_status_mask = 0; 
     8285+       if (I_IGNPAR(info->tty)) 
     8286+               info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; 
     8287+       if (I_IGNBRK(info->tty)) { 
     8288+               info->ignore_status_mask |= UART_LSR_BI; 
     8289+               /* 
     8290+                * If we're ignore parity and break indicators, ignore  
     8291+                * overruns too.  (For real raw support). 
     8292+                */ 
     8293+               if (I_IGNPAR(info->tty)) 
     8294+                       info->ignore_status_mask |= UART_LSR_OE; 
     8295+       } 
     8296+       /* 
     8297+        * !!! ignore all characters if CREAD is not set 
     8298+        */ 
     8299+       if ((cflag & CREAD) == 0) 
     8300+               info->ignore_status_mask |= UART_LSR_DR; 
     8301+       save_flags(flags); cli(); 
     8302+       if (uart_config[info->state->type].flags & UART_STARTECH) { 
     8303+               serial_outp(info, UART_LCR, 0xBF); 
     8304+               serial_outp(info, UART_EFR, 
     8305+                           (cflag & CRTSCTS) ? UART_EFR_CTS : 0); 
     8306+       } 
     8307+       serial_outp(info, UART_LCR, cval | UART_LCR_DLAB);      /* set DLAB */ 
     8308+       serial_outp(info, UART_DLL, quot & 0xff);       /* LS of divisor */ 
     8309+       serial_outp(info, UART_DLM, quot >> 8);         /* MS of divisor */ 
     8310+       if (info->state->type == PORT_16750) 
     8311+               serial_outp(info, UART_FCR, fcr);       /* set fcr */ 
     8312+       serial_outp(info, UART_LCR, cval);              /* reset DLAB */ 
     8313+       info->LCR = cval;                               /* Save LCR */ 
     8314+       if (info->state->type != PORT_16750) { 
     8315+               if (fcr & UART_FCR_ENABLE_FIFO) { 
     8316+                       /* emulated UARTs (Lucent Venus 167x) need two steps */ 
     8317+                       serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); 
     8318+               } 
     8319+               serial_outp(info, UART_FCR, fcr);       /* set fcr */ 
     8320+       } 
     8321+       restore_flags(flags); 
     8322+} 
     8323+ 
     8324+static void rs_put_char(struct tty_struct *tty, unsigned char ch) 
     8325+{ 
     8326+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     8327+       unsigned long flags; 
     8328+ 
     8329+       if (serial_paranoia_check(info, tty->device, "rs_put_char")) 
     8330+               return; 
     8331+ 
     8332+       if (!tty || !info->xmit.buf) 
     8333+               return; 
     8334+ 
     8335+       save_flags(flags); cli(); 
     8336+       if (CIRC_SPACE(info->xmit.head, 
     8337+                      info->xmit.tail, 
     8338+                      SERIAL_XMIT_SIZE) == 0) { 
     8339+               restore_flags(flags); 
     8340+               return; 
     8341+       } 
     8342+ 
     8343+       info->xmit.buf[info->xmit.head] = ch; 
     8344+       info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1); 
     8345+       restore_flags(flags); 
     8346+} 
     8347+ 
     8348+static void rs_flush_chars(struct tty_struct *tty) 
     8349+{ 
     8350+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     8351+       unsigned long flags; 
     8352+                                
     8353+       if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) 
     8354+               return; 
     8355+ 
     8356+       if (info->xmit.head == info->xmit.tail 
     8357+           || tty->stopped 
     8358+           || tty->hw_stopped 
     8359+           || !info->xmit.buf) 
     8360+               return; 
     8361+ 
     8362+       save_flags(flags); cli(); 
     8363+       info->IER |= UART_IER_THRI; 
     8364+       serial_out(info, UART_IER, info->IER); 
     8365+       restore_flags(flags); 
     8366+} 
     8367+ 
     8368+static int rs_write(struct tty_struct * tty, int from_user, 
     8369+                   const unsigned char *buf, int count) 
     8370+{ 
     8371+       int     c, ret = 0; 
     8372+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     8373+       unsigned long flags; 
     8374+                                
     8375+       if (serial_paranoia_check(info, tty->device, "rs_write")) 
     8376+               return 0; 
     8377+ 
     8378+       if (!tty || !info->xmit.buf || !tmp_buf) 
     8379+               return 0; 
     8380+ 
     8381+       save_flags(flags); 
     8382+       if (from_user) { 
     8383+               down(&tmp_buf_sem); 
     8384+               while (1) { 
     8385+                       int c1; 
     8386+                       c = CIRC_SPACE_TO_END(info->xmit.head, 
     8387+                                             info->xmit.tail, 
     8388+                                             SERIAL_XMIT_SIZE); 
     8389+                       if (count < c) 
     8390+                               c = count; 
     8391+                       if (c <= 0) 
     8392+                               break; 
     8393+ 
     8394+                       c -= copy_from_user(tmp_buf, buf, c); 
     8395+                       if (!c) { 
     8396+                               if (!ret) 
     8397+                                       ret = -EFAULT; 
     8398+                               break; 
     8399+                       } 
     8400+                       cli(); 
     8401+                       c1 = CIRC_SPACE_TO_END(info->xmit.head, 
     8402+                                              info->xmit.tail, 
     8403+                                              SERIAL_XMIT_SIZE); 
     8404+                       if (c1 < c) 
     8405+                               c = c1; 
     8406+                       memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); 
     8407+                       info->xmit.head = ((info->xmit.head + c) & 
     8408+                                          (SERIAL_XMIT_SIZE-1)); 
     8409+                       restore_flags(flags); 
     8410+                       buf += c; 
     8411+                       count -= c; 
     8412+                       ret += c; 
     8413+               } 
     8414+               up(&tmp_buf_sem); 
     8415+       } else { 
     8416+               cli(); 
     8417+               while (1) { 
     8418+                       c = CIRC_SPACE_TO_END(info->xmit.head, 
     8419+                                             info->xmit.tail, 
     8420+                                             SERIAL_XMIT_SIZE); 
     8421+                       if (count < c) 
     8422+                               c = count; 
     8423+                       if (c <= 0) { 
     8424+                               break; 
     8425+                       } 
     8426+                       memcpy(info->xmit.buf + info->xmit.head, buf, c); 
     8427+                       info->xmit.head = ((info->xmit.head + c) & 
     8428+                                          (SERIAL_XMIT_SIZE-1)); 
     8429+                       buf += c; 
     8430+                       count -= c; 
     8431+                       ret += c; 
     8432+               } 
     8433+               restore_flags(flags); 
     8434+       } 
     8435+       if (info->xmit.head != info->xmit.tail 
     8436+           && !tty->stopped 
     8437+           && !tty->hw_stopped 
     8438+           && !(info->IER & UART_IER_THRI)) { 
     8439+               info->IER |= UART_IER_THRI; 
     8440+               serial_out(info, UART_IER, info->IER); 
     8441+       } 
     8442+       return ret; 
     8443+} 
     8444+ 
     8445+static int rs_write_room(struct tty_struct *tty) 
     8446+{ 
     8447+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     8448+ 
     8449+       if (serial_paranoia_check(info, tty->device, "rs_write_room")) 
     8450+               return 0; 
     8451+       return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 
     8452+} 
     8453+ 
     8454+static int rs_chars_in_buffer(struct tty_struct *tty) 
     8455+{ 
     8456+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     8457+                                
     8458+       if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) 
     8459+               return 0; 
     8460+       return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 
     8461+} 
     8462+ 
     8463+static void rs_flush_buffer(struct tty_struct *tty) 
     8464+{ 
     8465+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     8466+       unsigned long flags; 
     8467+        
     8468+       if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) 
     8469+               return; 
     8470+       save_flags(flags); cli(); 
     8471+       info->xmit.head = info->xmit.tail = 0; 
     8472+       restore_flags(flags); 
     8473+#ifdef SERIAL_HAVE_POLL_WAIT 
     8474+       wake_up_interruptible(&tty->poll_wait); 
     8475+#endif 
     8476+       tty_wakeup(tty); 
     8477+} 
     8478+ 
     8479+/* 
     8480+ * This function is used to send a high-priority XON/XOFF character to 
     8481+ * the device 
     8482+ */ 
     8483+static void rs_send_xchar(struct tty_struct *tty, char ch) 
     8484+{ 
     8485+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     8486+ 
     8487+       if (serial_paranoia_check(info, tty->device, "rs_send_char")) 
     8488+               return; 
     8489+ 
     8490+       info->x_char = ch; 
     8491+       if (ch) { 
     8492+               /* Make sure transmit interrupts are on */ 
     8493+               info->IER |= UART_IER_THRI; 
     8494+               serial_out(info, UART_IER, info->IER); 
     8495+       } 
     8496+} 
     8497+ 
     8498+/* 
     8499+ * ------------------------------------------------------------ 
     8500+ * rs_throttle() 
     8501+ *  
     8502+ * This routine is called by the upper-layer tty layer to signal that 
     8503+ * incoming characters should be throttled. 
     8504+ * ------------------------------------------------------------ 
     8505+ */ 
     8506+static void rs_throttle(struct tty_struct * tty) 
     8507+{ 
     8508+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     8509+       unsigned long flags; 
     8510+#ifdef SERIAL_DEBUG_THROTTLE 
     8511+       char    buf[64]; 
     8512+        
     8513+       printk("throttle %s: %d....\n", tty_name(tty, buf), 
     8514+              tty->ldisc.chars_in_buffer(tty)); 
     8515+#endif 
     8516+ 
     8517+       if (serial_paranoia_check(info, tty->device, "rs_throttle")) 
     8518+               return; 
     8519+        
     8520+       if (I_IXOFF(tty)) 
     8521+               rs_send_xchar(tty, STOP_CHAR(tty)); 
     8522+ 
     8523+       if (tty->termios->c_cflag & CRTSCTS) 
     8524+               info->MCR &= ~UART_MCR_RTS; 
     8525+ 
     8526+       save_flags(flags); cli(); 
     8527+       serial_out(info, UART_MCR, info->MCR); 
     8528+       restore_flags(flags); 
     8529+} 
     8530+ 
     8531+static void rs_unthrottle(struct tty_struct * tty) 
     8532+{ 
     8533+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     8534+       unsigned long flags; 
     8535+#ifdef SERIAL_DEBUG_THROTTLE 
     8536+       char    buf[64]; 
     8537+        
     8538+       printk("unthrottle %s: %d....\n", tty_name(tty, buf), 
     8539+              tty->ldisc.chars_in_buffer(tty)); 
     8540+#endif 
     8541+ 
     8542+       if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) 
     8543+               return; 
     8544+        
     8545+       if (I_IXOFF(tty)) { 
     8546+               if (info->x_char) 
     8547+                       info->x_char = 0; 
     8548+               else 
     8549+                       rs_send_xchar(tty, START_CHAR(tty)); 
     8550+       } 
     8551+       if (tty->termios->c_cflag & CRTSCTS) 
     8552+               info->MCR |= UART_MCR_RTS; 
     8553+       save_flags(flags); cli(); 
     8554+       serial_out(info, UART_MCR, info->MCR); 
     8555+       restore_flags(flags); 
     8556+} 
     8557+ 
     8558+/* 
     8559+ * ------------------------------------------------------------ 
     8560+ * rs_ioctl() and friends 
     8561+ * ------------------------------------------------------------ 
     8562+ */ 
     8563+ 
     8564+static int get_serial_info(struct async_struct * info, 
     8565+                          struct serial_struct * retinfo) 
     8566+{ 
     8567+       struct serial_struct tmp; 
     8568+       struct serial_state *state = info->state; 
     8569+    
     8570+       if (!retinfo) 
     8571+               return -EFAULT; 
     8572+       memset(&tmp, 0, sizeof(tmp)); 
     8573+       tmp.type = state->type; 
     8574+       tmp.line = state->line; 
     8575+       tmp.port = state->port; 
     8576+       if (HIGH_BITS_OFFSET) 
     8577+               tmp.port_high = state->port >> HIGH_BITS_OFFSET; 
     8578+       else 
     8579+               tmp.port_high = 0; 
     8580+       tmp.irq = state->irq; 
     8581+       tmp.flags = state->flags; 
     8582+       tmp.xmit_fifo_size = state->xmit_fifo_size; 
     8583+       tmp.baud_base = state->baud_base; 
     8584+       tmp.close_delay = state->close_delay; 
     8585+       tmp.closing_wait = state->closing_wait; 
     8586+       tmp.custom_divisor = state->custom_divisor; 
     8587+       tmp.hub6 = state->hub6; 
     8588+       tmp.io_type = state->io_type; 
     8589+       if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) 
     8590+               return -EFAULT; 
     8591+       return 0; 
     8592+} 
     8593+ 
     8594+static int set_serial_info(struct async_struct * info, 
     8595+                          struct serial_struct * new_info) 
     8596+{ 
     8597+       struct serial_struct new_serial; 
     8598+       struct serial_state old_state, *state; 
     8599+       unsigned int            i,change_irq,change_port; 
     8600+       int                     retval = 0; 
     8601+       unsigned long           new_port; 
     8602+ 
     8603+       if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) 
     8604+               return -EFAULT; 
     8605+       state = info->state; 
     8606+       old_state = *state; 
     8607+ 
     8608+       new_port = new_serial.port; 
     8609+       if (HIGH_BITS_OFFSET) 
     8610+               new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; 
     8611+ 
     8612+       change_irq = new_serial.irq != state->irq; 
     8613+       change_port = (new_port != ((int) state->port)) || 
     8614+               (new_serial.hub6 != state->hub6); 
     8615 
     8616+       if (!capable(CAP_SYS_ADMIN)) { 
     8617+               if (change_irq || change_port || 
     8618+                   (new_serial.baud_base != state->baud_base) || 
     8619+                   (new_serial.type != state->type) || 
     8620+                   (new_serial.close_delay != state->close_delay) || 
     8621+                   (new_serial.xmit_fifo_size != state->xmit_fifo_size) || 
     8622+                   ((new_serial.flags & ~ASYNC_USR_MASK) != 
     8623+                    (state->flags & ~ASYNC_USR_MASK))) 
     8624+                       return -EPERM; 
     8625+               state->flags = ((state->flags & ~ASYNC_USR_MASK) | 
     8626+                              (new_serial.flags & ASYNC_USR_MASK)); 
     8627+               info->flags = ((info->flags & ~ASYNC_USR_MASK) | 
     8628+                              (new_serial.flags & ASYNC_USR_MASK)); 
     8629+               state->custom_divisor = new_serial.custom_divisor; 
     8630+               goto check_and_exit; 
     8631+       } 
     8632+ 
     8633+       new_serial.irq = irq_cannonicalize(new_serial.irq); 
     8634+ 
     8635+       if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||  
     8636+           (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) || 
     8637+           (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || 
     8638+           (new_serial.type == PORT_STARTECH)) { 
     8639+               return -EINVAL; 
     8640+       } 
     8641+ 
     8642+       if ((new_serial.type != state->type) || 
     8643+           (new_serial.xmit_fifo_size <= 0)) 
     8644+               new_serial.xmit_fifo_size = 
     8645+                       uart_config[new_serial.type].dfl_xmit_fifo_size; 
     8646+ 
     8647+       /* Make sure address is not already in use */ 
     8648+       if (new_serial.type) { 
     8649+               for (i = 0 ; i < NR_PORTS; i++) 
     8650+                       if ((state != &rs_table[i]) && 
     8651+                           (rs_table[i].io_type == SERIAL_IO_PORT) && 
     8652+                           (rs_table[i].port == new_port) && 
     8653+                           rs_table[i].type) 
     8654+                               return -EADDRINUSE; 
     8655+       } 
     8656+ 
     8657+       if ((change_port || change_irq) && (state->count > 1)) 
     8658+               return -EBUSY; 
     8659+ 
     8660+       /* 
     8661+        * OK, past this point, all the error checking has been done. 
     8662+        * At this point, we start making changes..... 
     8663+        */ 
     8664+ 
     8665+       state->baud_base = new_serial.baud_base; 
     8666+       state->flags = ((state->flags & ~ASYNC_FLAGS) | 
     8667+                       (new_serial.flags & ASYNC_FLAGS)); 
     8668+       info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | 
     8669+                      (info->flags & ASYNC_INTERNAL_FLAGS)); 
     8670+       state->custom_divisor = new_serial.custom_divisor; 
     8671+       state->close_delay = new_serial.close_delay * HZ/100; 
     8672+       state->closing_wait = new_serial.closing_wait * HZ/100; 
     8673+#if (LINUX_VERSION_CODE > 0x20100) 
     8674+       info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 
     8675+#endif 
     8676+       info->xmit_fifo_size = state->xmit_fifo_size = 
     8677+               new_serial.xmit_fifo_size; 
     8678+ 
     8679+       if ((state->type != PORT_UNKNOWN) && state->port) { 
     8680+#ifdef CONFIG_SERIAL_RSA 
     8681+               if (old_state.type == PORT_RSA) 
     8682+                       release_region(state->port + UART_RSA_BASE, 16); 
     8683+               else 
     8684+#endif 
     8685+               release_region(state->port,8); 
     8686+       } 
     8687+       state->type = new_serial.type; 
     8688+       if (change_port || change_irq) { 
     8689+               /* 
     8690+                * We need to shutdown the serial port at the old 
     8691+                * port/irq combination. 
     8692+                */ 
     8693+               shutdown(info); 
     8694+               state->irq = new_serial.irq; 
     8695+               info->port = state->port = new_port; 
     8696+               info->hub6 = state->hub6 = new_serial.hub6; 
     8697+               if (info->hub6) 
     8698+                       info->io_type = state->io_type = SERIAL_IO_HUB6; 
     8699+               else if (info->io_type == SERIAL_IO_HUB6) 
     8700+                       info->io_type = state->io_type = SERIAL_IO_PORT; 
     8701+       } 
     8702+       if ((state->type != PORT_UNKNOWN) && state->port) { 
     8703+#ifdef CONFIG_SERIAL_RSA 
     8704+               if (state->type == PORT_RSA) 
     8705+                       request_region(state->port + UART_RSA_BASE, 
     8706+                                      16, "serial_rsa(set)"); 
     8707+               else 
     8708+#endif 
     8709+                       request_region(state->port,8,"serial(set)"); 
     8710+       } 
     8711+ 
     8712+        
     8713+check_and_exit: 
     8714+       if ((!state->port && !state->iomem_base) || !state->type) 
     8715+               return 0; 
     8716+       if (info->flags & ASYNC_INITIALIZED) { 
     8717+               if (((old_state.flags & ASYNC_SPD_MASK) != 
     8718+                    (state->flags & ASYNC_SPD_MASK)) || 
     8719+                   (old_state.custom_divisor != state->custom_divisor)) { 
     8720+#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */ 
     8721+                       if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 
     8722+                               info->tty->alt_speed = 57600; 
     8723+                       if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 
     8724+                               info->tty->alt_speed = 115200; 
     8725+                       if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 
     8726+                               info->tty->alt_speed = 230400; 
     8727+                       if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 
     8728+                               info->tty->alt_speed = 460800; 
     8729+#endif 
     8730+                       change_speed(info, 0); 
     8731+               } 
     8732+       } else 
     8733+               retval = startup(info); 
     8734+       return retval; 
     8735+} 
     8736+ 
     8737+ 
     8738+/* 
     8739+ * get_lsr_info - get line status register info 
     8740+ * 
     8741+ * Purpose: Let user call ioctl() to get info when the UART physically 
     8742+ *         is emptied.  On bus types like RS485, the transmitter must 
     8743+ *         release the bus after transmitting. This must be done when 
     8744+ *         the transmit shift register is empty, not be done when the 
     8745+ *         transmit holding register is empty.  This functionality 
     8746+ *         allows an RS485 driver to be written in user space.  
     8747+ */ 
     8748+static int get_lsr_info(struct async_struct * info, unsigned int *value) 
     8749+{ 
     8750+       unsigned char status; 
     8751+       unsigned int result; 
     8752+       unsigned long flags; 
     8753+ 
     8754+       save_flags(flags); cli(); 
     8755+       status = serial_in(info, UART_LSR); 
     8756+       restore_flags(flags); 
     8757+       result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); 
     8758+ 
     8759+       /* 
     8760+        * If we're about to load something into the transmit 
     8761+        * register, we'll pretend the transmitter isn't empty to 
     8762+        * avoid a race condition (depending on when the transmit 
     8763+        * interrupt happens). 
     8764+        */ 
     8765+       if (info->x_char ||  
     8766+           ((CIRC_CNT(info->xmit.head, info->xmit.tail, 
     8767+                      SERIAL_XMIT_SIZE) > 0) && 
     8768+            !info->tty->stopped && !info->tty->hw_stopped)) 
     8769+               result &= ~TIOCSER_TEMT; 
     8770+ 
     8771+       if (copy_to_user(value, &result, sizeof(int))) 
     8772+               return -EFAULT; 
     8773+       return 0; 
     8774+} 
     8775+ 
     8776+ 
     8777+static int get_modem_info(struct async_struct * info, unsigned int *value) 
     8778+{ 
     8779+       unsigned char control, status; 
     8780+       unsigned int result; 
     8781+       unsigned long flags; 
     8782+ 
     8783+       control = info->MCR; 
     8784+       save_flags(flags); cli(); 
     8785+       status = serial_in(info, UART_MSR); 
     8786+       restore_flags(flags); 
     8787+       result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) 
     8788+               | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) 
     8789+#ifdef TIOCM_OUT1 
     8790+               | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0) 
     8791+               | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0) 
     8792+#endif 
     8793+               | ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0) 
     8794+               | ((status  & UART_MSR_RI) ? TIOCM_RNG : 0) 
     8795+               | ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0) 
     8796+               | ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0); 
     8797+ 
     8798+       if (copy_to_user(value, &result, sizeof(int))) 
     8799+               return -EFAULT; 
     8800+       return 0; 
     8801+} 
     8802+ 
     8803+static int set_modem_info(struct async_struct * info, unsigned int cmd, 
     8804+                         unsigned int *value) 
     8805+{ 
     8806+       unsigned int arg; 
     8807+       unsigned long flags; 
     8808+ 
     8809+       if (copy_from_user(&arg, value, sizeof(int))) 
     8810+               return -EFAULT; 
     8811+ 
     8812+       switch (cmd) { 
     8813+       case TIOCMBIS:  
     8814+               if (arg & TIOCM_RTS) 
     8815+                       info->MCR |= UART_MCR_RTS; 
     8816+               if (arg & TIOCM_DTR) 
     8817+                       info->MCR |= UART_MCR_DTR; 
     8818+#ifdef TIOCM_OUT1 
     8819+               if (arg & TIOCM_OUT1) 
     8820+                       info->MCR |= UART_MCR_OUT1; 
     8821+               if (arg & TIOCM_OUT2) 
     8822+                       info->MCR |= UART_MCR_OUT2; 
     8823+#endif 
     8824+               if (arg & TIOCM_LOOP) 
     8825+                       info->MCR |= UART_MCR_LOOP; 
     8826+               break; 
     8827+       case TIOCMBIC: 
     8828+               if (arg & TIOCM_RTS) 
     8829+                       info->MCR &= ~UART_MCR_RTS; 
     8830+               if (arg & TIOCM_DTR) 
     8831+                       info->MCR &= ~UART_MCR_DTR; 
     8832+#ifdef TIOCM_OUT1 
     8833+               if (arg & TIOCM_OUT1) 
     8834+                       info->MCR &= ~UART_MCR_OUT1; 
     8835+               if (arg & TIOCM_OUT2) 
     8836+                       info->MCR &= ~UART_MCR_OUT2; 
     8837+#endif 
     8838+               if (arg & TIOCM_LOOP) 
     8839+                       info->MCR &= ~UART_MCR_LOOP; 
     8840+               break; 
     8841+       case TIOCMSET: 
     8842+               info->MCR = ((info->MCR & ~(UART_MCR_RTS | 
     8843+#ifdef TIOCM_OUT1 
     8844+                                           UART_MCR_OUT1 | 
     8845+                                           UART_MCR_OUT2 | 
     8846+#endif 
     8847+                                           UART_MCR_LOOP | 
     8848+                                           UART_MCR_DTR)) 
     8849+                            | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0) 
     8850+#ifdef TIOCM_OUT1 
     8851+                            | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0) 
     8852+                            | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0) 
     8853+#endif 
     8854+                            | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0) 
     8855+                            | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0)); 
     8856+               break; 
     8857+       default: 
     8858+               return -EINVAL; 
     8859+       } 
     8860+       save_flags(flags); cli(); 
     8861+       info->MCR |= ALPHA_KLUDGE_MCR;          /* Don't ask */ 
     8862+       serial_out(info, UART_MCR, info->MCR); 
     8863+       restore_flags(flags); 
     8864+       return 0; 
     8865+} 
     8866+ 
     8867+static int do_autoconfig(struct async_struct * info) 
     8868+{ 
     8869+       int irq, retval; 
     8870+        
     8871+       if (!capable(CAP_SYS_ADMIN)) 
     8872+               return -EPERM; 
     8873+        
     8874+       if (info->state->count > 1) 
     8875+               return -EBUSY; 
     8876+        
     8877+       shutdown(info); 
     8878+ 
     8879+       autoconfig(info->state); 
     8880+       if ((info->state->flags & ASYNC_AUTO_IRQ) && 
     8881+           (info->state->port != 0  || info->state->iomem_base != 0) && 
     8882+           (info->state->type != PORT_UNKNOWN)) { 
     8883+               irq = detect_uart_irq(info->state); 
     8884+               if (irq > 0) 
     8885+                       info->state->irq = irq; 
     8886+       } 
     8887+ 
     8888+       retval = startup(info); 
     8889+       if (retval) 
     8890+               return retval; 
     8891+       return 0; 
     8892+} 
     8893+ 
     8894+/* 
     8895+ * rs_break() --- routine which turns the break handling on or off 
     8896+ */ 
     8897+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ 
     8898+static void send_break(        struct async_struct * info, int duration) 
     8899+{ 
     8900+       if (!CONFIGURED_SERIAL_PORT(info)) 
     8901+               return; 
     8902+       current->state = TASK_INTERRUPTIBLE; 
     8903+       current->timeout = jiffies + duration; 
     8904+       cli(); 
     8905+       info->LCR |= UART_LCR_SBC; 
     8906+       serial_out(info, UART_LCR, info->LCR); 
     8907+       schedule(); 
     8908+       info->LCR &= ~UART_LCR_SBC; 
     8909+       serial_out(info, UART_LCR, info->LCR); 
     8910+       sti(); 
     8911+} 
     8912+#else 
     8913+static void rs_break(struct tty_struct *tty, int break_state) 
     8914+{ 
     8915+       struct async_struct * info = (struct async_struct *)tty->driver_data; 
     8916+       unsigned long flags; 
     8917+        
     8918+       if (serial_paranoia_check(info, tty->device, "rs_break")) 
     8919+               return; 
     8920+ 
     8921+       if (!CONFIGURED_SERIAL_PORT(info)) 
     8922+               return; 
     8923+       save_flags(flags); cli(); 
     8924+       if (break_state == -1) 
     8925+               info->LCR |= UART_LCR_SBC; 
     8926+       else 
     8927+               info->LCR &= ~UART_LCR_SBC; 
     8928+       serial_out(info, UART_LCR, info->LCR); 
     8929+       restore_flags(flags); 
     8930+} 
     8931+#endif 
     8932+ 
     8933+#ifdef CONFIG_SERIAL_MULTIPORT 
     8934+static int get_multiport_struct(struct async_struct * info, 
     8935+                               struct serial_multiport_struct *retinfo) 
     8936+{ 
     8937+       struct serial_multiport_struct ret; 
     8938+       struct rs_multiport_struct *multi; 
     8939+        
     8940+       multi = &rs_multiport[info->state->irq]; 
     8941+ 
     8942+       ret.port_monitor = multi->port_monitor; 
     8943+        
     8944+       ret.port1 = multi->port1; 
     8945+       ret.mask1 = multi->mask1; 
     8946+       ret.match1 = multi->match1; 
     8947+        
     8948+       ret.port2 = multi->port2; 
     8949+       ret.mask2 = multi->mask2; 
     8950+       ret.match2 = multi->match2; 
     8951+        
     8952+       ret.port3 = multi->port3; 
     8953+       ret.mask3 = multi->mask3; 
     8954+       ret.match3 = multi->match3; 
     8955+        
     8956+       ret.port4 = multi->port4; 
     8957+       ret.mask4 = multi->mask4; 
     8958+       ret.match4 = multi->match4; 
     8959+ 
     8960+       ret.irq = info->state->irq; 
     8961+ 
     8962+       if (copy_to_user(retinfo,&ret,sizeof(*retinfo))) 
     8963+               return -EFAULT; 
     8964+       return 0; 
     8965+} 
     8966+ 
     8967+static int set_multiport_struct(struct async_struct * info, 
     8968+                               struct serial_multiport_struct *in_multi) 
     8969+{ 
     8970+       struct serial_multiport_struct new_multi; 
     8971+       struct rs_multiport_struct *multi; 
     8972+       struct serial_state *state; 
     8973+       int     was_multi, now_multi; 
     8974+       int     retval; 
     8975+       void (*handler)(int, void *, struct pt_regs *); 
     8976+ 
     8977+       if (!capable(CAP_SYS_ADMIN)) 
     8978+               return -EPERM; 
     8979+       state = info->state; 
     8980+        
     8981+       if (copy_from_user(&new_multi, in_multi, 
     8982+                          sizeof(struct serial_multiport_struct))) 
     8983+               return -EFAULT; 
     8984+        
     8985+       if (new_multi.irq != state->irq || state->irq == 0 || 
     8986+           !IRQ_ports[state->irq]) 
     8987+               return -EINVAL; 
     8988+ 
     8989+       multi = &rs_multiport[state->irq]; 
     8990+       was_multi = (multi->port1 != 0); 
     8991+        
     8992+       multi->port_monitor = new_multi.port_monitor; 
     8993+        
     8994+       if (multi->port1) 
     8995+               release_region(multi->port1,1); 
     8996+       multi->port1 = new_multi.port1; 
     8997+       multi->mask1 = new_multi.mask1; 
     8998+       multi->match1 = new_multi.match1; 
     8999+       if (multi->port1) 
     9000+               request_region(multi->port1,1,"serial(multiport1)"); 
     9001+ 
     9002+       if (multi->port2) 
     9003+               release_region(multi->port2,1); 
     9004+       multi->port2 = new_multi.port2; 
     9005+       multi->mask2 = new_multi.mask2; 
     9006+       multi->match2 = new_multi.match2; 
     9007+       if (multi->port2) 
     9008+               request_region(multi->port2,1,"serial(multiport2)"); 
     9009+ 
     9010+       if (multi->port3) 
     9011+               release_region(multi->port3,1); 
     9012+       multi->port3 = new_multi.port3; 
     9013+       multi->mask3 = new_multi.mask3; 
     9014+       multi->match3 = new_multi.match3; 
     9015+       if (multi->port3) 
     9016+               request_region(multi->port3,1,"serial(multiport3)"); 
     9017+ 
     9018+       if (multi->port4) 
     9019+               release_region(multi->port4,1); 
     9020+       multi->port4 = new_multi.port4; 
     9021+       multi->mask4 = new_multi.mask4; 
     9022+       multi->match4 = new_multi.match4; 
     9023+       if (multi->port4) 
     9024+               request_region(multi->port4,1,"serial(multiport4)"); 
     9025+ 
     9026+       now_multi = (multi->port1 != 0); 
     9027+        
     9028+       if (IRQ_ports[state->irq]->next_port && 
     9029+           (was_multi != now_multi)) { 
     9030+               free_irq(state->irq, &IRQ_ports[state->irq]); 
     9031+               if (now_multi) 
     9032+                       handler = rs_interrupt_multi; 
     9033+               else 
     9034+                       handler = rs_interrupt; 
     9035+ 
     9036+               retval = request_irq(state->irq, handler, SA_SHIRQ, 
     9037+                                    "serial", &IRQ_ports[state->irq]); 
     9038+               if (retval) { 
     9039+                       printk("Couldn't reallocate serial interrupt " 
     9040+                              "driver!!\n"); 
     9041+               } 
     9042+       } 
     9043+       return 0; 
     9044+} 
     9045+#endif 
     9046+ 
     9047+static int rs_ioctl(struct tty_struct *tty, struct file * file, 
     9048+                   unsigned int cmd, unsigned long arg) 
     9049+{ 
     9050+       struct async_struct * info = (struct async_struct *)tty->driver_data; 
     9051+       struct async_icount cprev, cnow;        /* kernel counter temps */ 
     9052+       struct serial_icounter_struct icount; 
     9053+       unsigned long flags; 
     9054+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ 
     9055+       int retval, tmp; 
     9056+#endif 
     9057+        
     9058+       if (serial_paranoia_check(info, tty->device, "rs_ioctl")) 
     9059+               return -ENODEV; 
     9060+ 
     9061+       if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && 
     9062+           (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && 
     9063+           (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { 
     9064+               if (tty->flags & (1 << TTY_IO_ERROR)) 
     9065+                   return -EIO; 
     9066+       } 
     9067+        
     9068+       switch (cmd) { 
     9069+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ 
     9070+               case TCSBRK:    /* SVID version: non-zero arg --> no break */ 
     9071+                       retval = tty_check_change(tty); 
     9072+                       if (retval) 
     9073+                               return retval; 
     9074+                       tty_wait_until_sent(tty, 0); 
     9075+                       if (signal_pending(current)) 
     9076+                               return -EINTR; 
     9077+                       if (!arg) { 
     9078+                               send_break(info, HZ/4); /* 1/4 second */ 
     9079+                               if (signal_pending(current)) 
     9080+                                       return -EINTR; 
     9081+                       } 
     9082+                       return 0; 
     9083+               case TCSBRKP:   /* support for POSIX tcsendbreak() */ 
     9084+                       retval = tty_check_change(tty); 
     9085+                       if (retval) 
     9086+                               return retval; 
     9087+                       tty_wait_until_sent(tty, 0); 
     9088+                       if (signal_pending(current)) 
     9089+                               return -EINTR; 
     9090+                       send_break(info, arg ? arg*(HZ/10) : HZ/4); 
     9091+                       if (signal_pending(current)) 
     9092+                               return -EINTR; 
     9093+                       return 0; 
     9094+               case TIOCGSOFTCAR: 
     9095+                       tmp = C_CLOCAL(tty) ? 1 : 0; 
     9096+                       if (copy_to_user((void *)arg, &tmp, sizeof(int))) 
     9097+                               return -EFAULT; 
     9098+                       return 0; 
     9099+               case TIOCSSOFTCAR: 
     9100+                       if (copy_from_user(&tmp, (void *)arg, sizeof(int))) 
     9101+                               return -EFAULT; 
     9102+ 
     9103+                       tty->termios->c_cflag = 
     9104+                               ((tty->termios->c_cflag & ~CLOCAL) | 
     9105+                                (tmp ? CLOCAL : 0)); 
     9106+                       return 0; 
     9107+#endif 
     9108+               case TIOCMGET: 
     9109+                       return get_modem_info(info, (unsigned int *) arg); 
     9110+               case TIOCMBIS: 
     9111+               case TIOCMBIC: 
     9112+               case TIOCMSET: 
     9113+                       return set_modem_info(info, cmd, (unsigned int *) arg); 
     9114+               case TIOCGSERIAL: 
     9115+                       return get_serial_info(info, 
     9116+                                              (struct serial_struct *) arg); 
     9117+               case TIOCSSERIAL: 
     9118+                       return set_serial_info(info, 
     9119+                                              (struct serial_struct *) arg); 
     9120+               case TIOCSERCONFIG: 
     9121+                       return do_autoconfig(info); 
     9122+ 
     9123+               case TIOCSERGETLSR: /* Get line status register */ 
     9124+                       return get_lsr_info(info, (unsigned int *) arg); 
     9125+ 
     9126+               case TIOCSERGSTRUCT: 
     9127+                       if (copy_to_user((struct async_struct *) arg, 
     9128+                                        info, sizeof(struct async_struct))) 
     9129+                               return -EFAULT; 
     9130+                       return 0; 
     9131+                                
     9132+#ifdef CONFIG_SERIAL_MULTIPORT 
     9133+               case TIOCSERGETMULTI: 
     9134+                       return get_multiport_struct(info, 
     9135+                                      (struct serial_multiport_struct *) arg); 
     9136+               case TIOCSERSETMULTI: 
     9137+                       return set_multiport_struct(info, 
     9138+                                      (struct serial_multiport_struct *) arg); 
     9139+#endif 
     9140+                        
     9141+               /* 
     9142+                * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change 
     9143+                * - mask passed in arg for lines of interest 
     9144+                *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) 
     9145+                * Caller should use TIOCGICOUNT to see which one it was 
     9146+                */ 
     9147+               case TIOCMIWAIT: 
     9148+                       save_flags(flags); cli(); 
     9149+                       /* note the counters on entry */ 
     9150+                       cprev = info->state->icount; 
     9151+                       restore_flags(flags); 
     9152+                       /* Force modem status interrupts on */ 
     9153+                       info->IER |= UART_IER_MSI; 
     9154+                       serial_out(info, UART_IER, info->IER); 
     9155+                       while (1) { 
     9156+                               interruptible_sleep_on(&info->delta_msr_wait); 
     9157+                               /* see if a signal did it */ 
     9158+                               if (signal_pending(current)) 
     9159+                                       return -ERESTARTSYS; 
     9160+                               save_flags(flags); cli(); 
     9161+                               cnow = info->state->icount; /* atomic copy */ 
     9162+                               restore_flags(flags); 
     9163+                               if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&  
     9164+                                   cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) 
     9165+                                       return -EIO; /* no change => error */ 
     9166+                               if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || 
     9167+                                    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || 
     9168+                                    ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) || 
     9169+                                    ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { 
     9170+                                       return 0; 
     9171+                               } 
     9172+                               cprev = cnow; 
     9173+                       } 
     9174+                       /* NOTREACHED */ 
     9175+ 
     9176+               /*  
     9177+                * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) 
     9178+                * Return: write counters to the user passed counter struct 
     9179+                * NB: both 1->0 and 0->1 transitions are counted except for 
     9180+                *     RI where only 0->1 is counted. 
     9181+                */ 
     9182+               case TIOCGICOUNT: 
     9183+                       save_flags(flags); cli(); 
     9184+                       cnow = info->state->icount; 
     9185+                       restore_flags(flags); 
     9186+                       icount.cts = cnow.cts; 
     9187+                       icount.dsr = cnow.dsr; 
     9188+                       icount.rng = cnow.rng; 
     9189+                       icount.dcd = cnow.dcd; 
     9190+                       icount.rx = cnow.rx; 
     9191+                       icount.tx = cnow.tx; 
     9192+                       icount.frame = cnow.frame; 
     9193+                       icount.overrun = cnow.overrun; 
     9194+                       icount.parity = cnow.parity; 
     9195+                       icount.brk = cnow.brk; 
     9196+                       icount.buf_overrun = cnow.buf_overrun; 
     9197+                        
     9198+                       if (copy_to_user((void *)arg, &icount, sizeof(icount))) 
     9199+                               return -EFAULT; 
     9200+                       return 0; 
     9201+               case TIOCSERGWILD: 
     9202+               case TIOCSERSWILD: 
     9203+                       /* "setserial -W" is called in Debian boot */ 
     9204+                       printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); 
     9205+                       return 0; 
     9206+ 
     9207+               default: 
     9208+                       return -ENOIOCTLCMD; 
     9209+               } 
     9210+       return 0; 
     9211+} 
     9212+ 
     9213+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) 
     9214+{ 
     9215+       struct async_struct *info = (struct async_struct *)tty->driver_data; 
     9216+       unsigned long flags; 
     9217+       unsigned int cflag = tty->termios->c_cflag; 
     9218+        
     9219+       if (   (cflag == old_termios->c_cflag) 
     9220+           && (   RELEVANT_IFLAG(tty->termios->c_iflag)  
     9221+               == RELEVANT_IFLAG(old_termios->c_iflag))) 
     9222+         return; 
     9223+ 
     9224+       change_speed(info, old_termios); 
     9225+ 
     9226+       /* Handle transition to B0 status */ 
     9227+       if ((old_termios->c_cflag & CBAUD) && 
     9228+           !(cflag & CBAUD)) { 
     9229+               info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); 
     9230+               save_flags(flags); cli(); 
     9231+               serial_out(info, UART_MCR, info->MCR); 
     9232+               restore_flags(flags); 
     9233+       } 
     9234+        
     9235+       /* Handle transition away from B0 status */ 
     9236+       if (!(old_termios->c_cflag & CBAUD) && 
     9237+           (cflag & CBAUD)) { 
     9238+               info->MCR |= UART_MCR_DTR; 
     9239+               if (!(tty->termios->c_cflag & CRTSCTS) ||  
     9240+                   !test_bit(TTY_THROTTLED, &tty->flags)) { 
     9241+                       info->MCR |= UART_MCR_RTS; 
     9242+               } 
     9243+               save_flags(flags); cli(); 
     9244+               serial_out(info, UART_MCR, info->MCR); 
     9245+               restore_flags(flags); 
     9246+       } 
     9247+        
     9248+       /* Handle turning off CRTSCTS */ 
     9249+       if ((old_termios->c_cflag & CRTSCTS) && 
     9250+           !(tty->termios->c_cflag & CRTSCTS)) { 
     9251+               tty->hw_stopped = 0; 
     9252+               rs_start(tty); 
     9253+       } 
     9254+ 
     9255+#if 0 
     9256+       /* 
     9257+        * No need to wake up processes in open wait, since they 
     9258+        * sample the CLOCAL flag once, and don't recheck it. 
     9259+        * XXX  It's not clear whether the current behavior is correct 
     9260+        * or not.  Hence, this may change..... 
     9261+        */ 
     9262+       if (!(old_termios->c_cflag & CLOCAL) && 
     9263+           (tty->termios->c_cflag & CLOCAL)) 
     9264+               wake_up_interruptible(&info->open_wait); 
     9265+#endif 
     9266+} 
     9267+ 
     9268+/* 
     9269+ * ------------------------------------------------------------ 
     9270+ * rs_close() 
     9271+ *  
     9272+ * This routine is called when the serial port gets closed.  First, we 
     9273+ * wait for the last remaining data to be sent.  Then, we unlink its 
     9274+ * async structure from the interrupt chain if necessary, and we free 
     9275+ * that IRQ if nothing is left in the chain. 
     9276+ * ------------------------------------------------------------ 
     9277+ */ 
     9278+static void rs_close(struct tty_struct *tty, struct file * filp) 
     9279+{ 
     9280+       struct async_struct * info = (struct async_struct *)tty->driver_data; 
     9281+       struct serial_state *state; 
     9282+       unsigned long flags; 
     9283+ 
     9284+       if (!info || serial_paranoia_check(info, tty->device, "rs_close")) 
     9285+               return; 
     9286+ 
     9287+       state = info->state; 
     9288+        
     9289+       save_flags(flags); cli(); 
     9290+        
     9291+       if (tty_hung_up_p(filp)) { 
     9292+               DBG_CNT("before DEC-hung"); 
     9293+               MOD_DEC_USE_COUNT; 
     9294+               restore_flags(flags); 
     9295+               return; 
     9296+       } 
     9297+        
     9298+#ifdef SERIAL_DEBUG_OPEN 
     9299+       printk("rs_close ttys%d, count = %d\n", info->line, state->count); 
     9300+#endif 
     9301+       if ((tty->count == 1) && (state->count != 1)) { 
     9302+               /* 
     9303+                * Uh, oh.  tty->count is 1, which means that the tty 
     9304+                * structure will be freed.  state->count should always 
     9305+                * be one in these conditions.  If it's greater than 
     9306+                * one, we've got real problems, since it means the 
     9307+                * serial port won't be shutdown. 
     9308+                */ 
     9309+               printk("rs_close: bad serial port count; tty->count is 1, " 
     9310+                      "state->count is %d\n", state->count); 
     9311+               state->count = 1; 
     9312+       } 
     9313+       if (--state->count < 0) { 
     9314+               printk("rs_close: bad serial port count for ttys%d: %d\n", 
     9315+                      info->line, state->count); 
     9316+               state->count = 0; 
     9317+       } 
     9318+       if (state->count) { 
     9319+               DBG_CNT("before DEC-2"); 
     9320+               MOD_DEC_USE_COUNT; 
     9321+               restore_flags(flags); 
     9322+               return; 
     9323+       } 
     9324+       info->flags |= ASYNC_CLOSING; 
     9325+       restore_flags(flags); 
     9326+       /* 
     9327+        * Save the termios structure, since this port may have 
     9328+        * separate termios for callout and dialin. 
     9329+        */ 
     9330+       if (info->flags & ASYNC_NORMAL_ACTIVE) 
     9331+               info->state->normal_termios = *tty->termios; 
     9332+       if (info->flags & ASYNC_CALLOUT_ACTIVE) 
     9333+               info->state->callou