port enough sendpoint support for DSM-G600 from D-Link 2.4.21-pre4
authorDobrica Pavlinusic <dpavlin@brr.lan>
Mon, 14 May 2007 03:35:40 +0000 (22:35 -0500)
committerDobrica Pavlinusic <dpavlin@brr.lan>
Mon, 14 May 2007 03:35:40 +0000 (22:35 -0500)
to have working serial console, and booting up to disk

Makefile
arch/ppc/kernel/open_pic.c
arch/ppc/platforms/sandpoint.c
arch/ppc/platforms/sandpoint_serial.h
drivers/char/serial.c
drivers/char/tty_io.c
include/asm-ppc/open_pic.h

index 0b87dad..e22b771 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,8 @@ EXTRAVERSION = .4
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
-ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+#ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+ARCH := ppc
 KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
 
 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -19,7 +20,7 @@ FINDHPATH     = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net $(HPATH)/math
 HOSTCC         = gcc
 HOSTCFLAGS     = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
 
-CROSS_COMPILE  =
+CROSS_COMPILE  = powerpc-linux-
 
 #
 # Include the make variables (CC, etc...)
index 98a8b28..2039ae1 100644 (file)
@@ -341,11 +341,20 @@ void __init openpic_init(int offset)
        }
        NumProcessors = ((t & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >>
                         OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1;
+//REX:
+#if 0  
        if (NumSources == 0)
                openpic_set_sources(0,
                                    ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
                                     OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1,
                                    NULL);
+#endif
+//REX: too :p
+#if 1
+       if (NumSources == 0)
+               openpic_set_sources(0, 122,
+                                   NULL);
+#endif
        printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n",
               version, NumProcessors, NumSources, OpenPIC);
        timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency);
@@ -412,7 +421,8 @@ void __init openpic_init(int offset)
        if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd);
        openpic_set_spurious(OPENPIC_VEC_SPURIOUS+offset);
 
-       openpic_disable_8259_pass_through();
+       //REX:
+       //openpic_disable_8259_pass_through();
 #ifdef CONFIG_EPIC_SERIAL_MODE
        openpic_eicr_set_clk(7);        /* Slowest value until we know better */
        openpic_enable_sie();
@@ -923,7 +933,8 @@ openpic_sleep_restore_intrs(void)
                openpic_write(&ISR[i]->Destination, save_irq_src_dest[i]);
        }
        openpic_set_spurious(OPENPIC_VEC_SPURIOUS+open_pic_irq_offset);
-       openpic_disable_8259_pass_through();
+       //REX:
+       //openpic_disable_8259_pass_through();
        for (i=0; i<NumProcessors; i++)
                openpic_write(&OpenPIC->Processor[i].Current_Task_Priority,
                              save_cpu_task_pri[i]);
index a074dd7..a3d3137 100644 (file)
 
 #include "sandpoint_serial.h"
 
+#include "sandpoint.h"
+
+//#define SYS_266 1
+#define SYS_200 1
+//#define SYS_166 1
+
+//REX:
+#if 0
 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
 extern int pckbd_getkeycode(unsigned int scancode);
 extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
@@ -106,6 +114,7 @@ extern char pckbd_unexpected_up(unsigned char keycode);
 extern void pckbd_leds(unsigned char leds);
 extern void pckbd_init_hw(void);
 extern unsigned char pckbd_sysrq_xlate[128];
+#endif 
 
 extern void gen550_progress(char *, unsigned short);
 extern void gen550_init(int, struct serial_struct *);
@@ -114,11 +123,25 @@ unsigned char __res[sizeof (bd_t)];
 
 static void sandpoint_halt(void);
 
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+       SERIAL_PORT_DFNS        /* Defined in <asm/serial.h> */
+};
+
+#endif
+
 /*
  * Define all of the IRQ senses and polarities.  Taken from the
  * Sandpoint X3 User's manual.
  */
 static u_char sandpoint_openpic_initsenses[] __initdata = {
+// REX
+#if 0
        (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* 0: SIOINT */
        (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* 2: PCI Slot 1 */
        (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* 3: PCI Slot 2 */
@@ -126,6 +149,13 @@ static u_char sandpoint_openpic_initsenses[] __initdata = {
        (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* 5: PCI Slot 4 */
        (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* 8: IDE (INT C) */
        (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE)       /* 9: IDE (INT D) */
+#else
+       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* 17, EPIC IRQ 1 - PCI1 - flash*/
+       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* 18, EPIC IRQ 2 - LAN*/
+       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* 19, EPIC IRQ 3 - Not used*/
+       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* 20, EPIC IRQ 4 - Not used*/
+       1
+#endif
 };
 
 /*
@@ -139,6 +169,8 @@ sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
             *      PCI IDSEL/INTPIN->INTLINE
             *         A   B   C   D
             */
+// REX
+#if 0
        {
                {16,  0,  0,  0},       /* IDSEL 11 - i8259 on Windbond */
                { 0,  0,  0,  0},       /* IDSEL 12 - unused */
@@ -149,9 +181,20 @@ sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
        };
 
        const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4;
+#else
+       {
+               {   0,  0,  0,  0 },    /* IDSEL 13 - mini-PCI */
+               {   1,  -1,  2,  0 },    /* IDSEL 14 - NEC USB2.0 */
+               {   3,  0,  0,  0 },    /* IDSEL 15 - ADM983 */
+               {   4,  0,  0,  0 }
+       };
+
+       const long min_idsel = 13, max_idsel = 16, irqs_per_slot = 4;
+#endif
        return PCI_IRQ_TABLE_LOOKUP;
 }
 
+#if 0 //REX
 static void __init
 sandpoint_setup_winbond_83553(struct pci_controller *hose)
 {
@@ -197,6 +240,35 @@ sandpoint_setup_winbond_83553(struct pci_controller *hose)
         */
        early_write_config_dword(hose, 0, devfn, 0x40, 0x00ff0011);
 }
+#endif
+
+#ifndef CONFIG_SANDPOINT_X3
+/* On the sandpoint X2, we must avoid sending configuration cycles to
+ * device #12 (IDSEL addr = AD12).
+ */
+static int                     
+sandpoint_exclude_device(u_char bus, u_char devfn)
+{
+#if 0
+       if ((bus == 0) && (PCI_SLOT(devfn) == SANDPOINT_HOST_BRIDGE_IDSEL))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       else
+               return PCIBIOS_SUCCESSFUL;
+#endif
+#ifdef REX_DBG_PCI
+       printk("REX_DBG_PCI: dev-fun is %X:%X.\n",PCI_SLOT(devfn), PCI_FUNC(devfn));
+#endif 
+       if ((bus == 0) && (PCI_SLOT(devfn) == SANDPOINT_HOST_BRIDGE_IDSEL))
+       {
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       }
+       else
+       {
+               return PCIBIOS_SUCCESSFUL;
+       }       
+
+}
+#endif
 
 static void __init
 sandpoint_find_bridges(void)
@@ -211,12 +283,22 @@ sandpoint_find_bridges(void)
        hose->first_busno = 0;
        hose->last_busno = 0xff;
 
+//REX
+#if 0
        if (mpc10x_bridge_init(hose,
                               MPC10X_MEM_MAP_B,
                               MPC10X_MEM_MAP_B, MPC10X_MAPB_EUMB_BASE) == 0) {
+#endif
+       if (mpc10x_bridge_init(hose,
+                              MPC10X_MEM_MAP_B,
+                              MPC10X_MEM_MAP_B,
+                              0xfc000000) == 0) {
 
                /* Do early winbond init, then scan PCI bus */
-               sandpoint_setup_winbond_83553(hose);
+               //sandpoint_setup_winbond_83553(hose);
+#ifndef CONFIG_SANDPOINT_X3
+               ppc_md.pci_exclude_device = sandpoint_exclude_device;
+#endif
                hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
 
                ppc_md.pcibios_fixup = NULL;
@@ -321,7 +403,7 @@ sandpoint_setup_arch(void)
        }
 #endif
 }
-
+#if 0 //REX:
 #define        SANDPOINT_87308_CFG_ADDR                0x15c
 #define        SANDPOINT_87308_CFG_DATA                0x15d
 
@@ -389,11 +471,13 @@ sandpoint_fix_winbond_83553(void)
 
        return;
 }
+#endif //REX:
 
 static void __init
 sandpoint_init2(void)
 {
        /* Do Sandpoint board specific initialization.  */
+#if 0  
        sandpoint_fix_winbond_83553();
        sandpoint_setup_natl_87308();
 
@@ -403,7 +487,7 @@ sandpoint_init2(void)
        request_region(0x80, 0x10, "dma page reg");
        request_region(0xa0, 0x20, "pic2");
        request_region(0xc0, 0x20, "dma2");
-
+#endif //REX:
        return;
 }
 
@@ -427,6 +511,9 @@ sandpoint_init_IRQ(void)
         * as offsets starting at 0x50200, we need to adjust occordinly.
         */
 
+#if 1
+#ifdef CONFIG_SANDPOINT_X3
+//REX
        /* Map serial interrupt 0 */
        openpic_set_sources(0, 1, OpenPIC_Addr + 0x10200);
        /* Map serial interrupts 2-5 */
@@ -438,25 +525,86 @@ sandpoint_init_IRQ(void)
        /* Skip reserved space and map Message Unit Interrupt (I2O) */
        openpic_set_sources(10, 1, OpenPIC_Addr + 0x110C0);
 
-       openpic_init(NUM_8259_INTERRUPTS);
-       /* The cascade is on EPIC IRQ 0 (Linux IRQ 16). */
-       openpic_hookup_cascade(16, "8259 cascade to EPIC", &i8259_irq);
+       openpic_set_sources(0, 138, NULL);
+#else
+       /* Map EPIC IRQs 0-3 */
+       openpic_set_sources(0, 5, OpenPIC_Addr + 0x10200);
+       /* Skip reserved space and map i2c and DMA Ch[01] */
+       openpic_set_sources(113, 3, OpenPIC_Addr + 0x11020);
+       /* Skip reserved space and map Message Unit Interrupt (I2O) */
+       openpic_set_sources(118, 1, OpenPIC_Addr + 0x110C0);
+       //REX: UART
+       openpic_set_sources(121, 1, OpenPIC_Addr + 0x11120); //ttyS0
+       
+       openpic_set_sources(122, 1, OpenPIC_Addr + 0x11140);    //ttyS1 jackl
+#endif
+#endif 
+#if 1 //REX:
+#if 0//by Musenki, cause it will panic!
+       openpic_set_sources(0, 32, NULL);
+       openpic_set_sources(129, 3, NULL);//I2C
+       openpic_set_sources(134, 1, NULL);//Mesg
+       openpic_set_sources(137, 2, NULL);//DUART
+#endif 
+       //openpic_init(1, 0, 0, -1);
+       openpic_init(0);
+       /* The cascade is either on EPIC IRQ 1 or 2 on an X2 or on X3 it's
+        * on EPIC IRQ 0.
+        */
+       //openpic_hookup_cascade(SANDPOINT_SIO_IRQ, "8259 cascade to EPIC",
+       //              &i8259_irq);
 
        /*
         * openpic_init() has set up irq_desc[0-23] to be openpic
         * interrupts.  We need to set irq_desc[0-15] to be 8259 interrupts.
         * We then need to request and enable the 8259 irq.
         */
-       for (i = 0; i < NUM_8259_INTERRUPTS; i++)
-               irq_desc[i].handler = &i8259_pic;
+       //for (i = 0; i < NUM_8259_INTERRUPTS; i++)
+       //      irq_desc[i].handler = &i8259_pic;
 
        /*
         * The EPIC allows for a read in the range of 0xFEF00000 ->
         * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
         */
-       i8259_init(0xfef00000);
+       //i8259_init(0xfef00000);
+#endif //REX:  
 }
 
+/*
+ * Because the Sandpoint X2 has the i8259 cascade sharing an IRQ with a
+ * PCI device, if we have a possible cascade IRQ we need to see if the
+ * i8259 has something pending.  The only issue here is that the cascade
+ * IRQs will get a higher priority than an OpenPIC one, but this should be
+ * OK.
+ */
+static int
+sandpoint_get_irq(struct pt_regs *regs)
+{
+        int irq, cascade_irq;
+
+       irq = openpic_irq();
+       //REX:
+#if 0
+       if ((irq != 127)&&(irq != 2)&&(irq!=121))
+               printk("sandpoint_get_irq: irq = %d\n", irq);
+#endif 
+       //if (irq == SANDPOINT_SIO_IRQ) 
+       //REX:
+       if (0)
+       {
+               cascade_irq = i8259_irq(regs);
+
+               if (cascade_irq != -1) {
+                       irq = cascade_irq;
+                       openpic_eoi();
+               }
+       } else if (irq == OPENPIC_VEC_SPURIOUS) 
+               irq = -1;
+
+       return irq;
+}
+//REX:
+#if 0
 static u32
 sandpoint_irq_cannonicalize(u32 irq)
 {
@@ -465,6 +613,7 @@ sandpoint_irq_cannonicalize(u32 irq)
        else
                return irq;
 }
+#endif
 
 static unsigned long __init
 sandpoint_find_end_of_memory(void)
@@ -472,7 +621,11 @@ sandpoint_find_end_of_memory(void)
        bd_t *bp = (bd_t *) __res;
 
        if (bp->bi_memsize)
+       {
+       //REX:  
+               printk("Total memory %d MB.\n", bp->bi_memsize);
                return bp->bi_memsize;
+       }
 
        /* This might be fixed in DINK32 12.4, or we'll have another
         * way to determine the correct memory size anyhow. */
@@ -483,20 +636,45 @@ sandpoint_find_end_of_memory(void)
 static void __init
 sandpoint_map_io(void)
 {
-       io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
+       io_block_mapping(0xfc000000, 0xfc000000, 0x04000000, _PAGE_IO);
+       //REX:
+       //rs_table[0].iomem_base = ioremap_base - 0x100000 + 0x4500; 
 }
 
+/*
+ * Due to Sandpoint X2 errata, the Port 92 will not work.
+ */
 static void
 sandpoint_restart(char *cmd)
 {
-       __cli();
+       ulong msr, addr;
+       //printk("Jumping to start address...\n");
 
+       __cli();
+//REX:
+#if 1
        /* Set exception prefix high - to the firmware */
        _nmask_and_or_msr(0, MSR_IP);
 
        /* Reset system via Port 92 */
-       outb(0x00, 0x92);
-       outb(0x01, 0x92);
+       //outb(0x00, 0x92);
+       //outb(0x01, 0x92);
+#endif
+
+        /* Interrupts and MMU off */
+        __asm__ ("mtspr    81, 0");
+
+        /* Interrupts and MMU off */
+        __asm__ __volatile__ ("mfmsr    %0":"=r" (msr):);
+
+        msr &= ~0x1030;
+        __asm__ __volatile__ ("mtmsr    %0"::"r" (msr));       
+        /*
+        *          * Trying to execute the next instruction at a non-existing address
+        *          * should cause a machine check, resulting in reset
+        **/
+               addr = 0xFFF00100;
+        ((void (*)(void)) addr) ();
        for (;;) ;              /* Spin until reset happens */
 }
 
@@ -523,7 +701,7 @@ sandpoint_show_cpuinfo(struct seq_file *m)
 
        return 0;
 }
-
+#if 0 //REX:
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
 /*
  * IDE support.
@@ -621,6 +799,7 @@ sandpoint_ide_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port,
        return;
 }
 #endif
+#endif //REX:
 
 /*
  * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1.
@@ -628,12 +807,12 @@ sandpoint_ide_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port,
 static __inline__ void
 sandpoint_set_bat(void)
 {
-#if 1
+//REX:
+#if 0
        mb();
        mtspr(DBAT1U, 0xf8000ffe);
        mtspr(DBAT1L, 0xf800002a);
        mb();
-#else
        unsigned long bat3u, bat3l;
 
        __asm__ __volatile__(" lis %0,0xf800\n  \
@@ -644,8 +823,76 @@ sandpoint_set_bat(void)
                        isync\n                 \
                        sync ":"=r"(bat3u), "=r"(bat3l));
 #endif
+       unsigned long bat3u, bat3l;
+
+       __asm__ __volatile__(
+                       " lis %0,0xf000\n       \
+                       ori %1,%0,0x002a\n      \
+                       ori %0,%0,0x1fff\n      \
+                       mtspr 0x21e,%0\n        \
+                       mtspr 0x21f,%1\n        \
+                       isync\n                 \
+                       sync "
+                       : "=r" (bat3u), "=r" (bat3l));
+       
+       
 }
 
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+
+
+volatile unsigned char *com_port;
+volatile unsigned char *com_port_lsr;
+
+static void
+serial_writechar(char c)
+{
+       while ((*com_port_lsr & UART_LSR_THRE) == 0)
+               ;
+       *com_port = c;
+}
+
+void
+sandpoint_progress(char *s, unsigned short hex)
+{
+       volatile char c;
+
+       //jackl
+       com_port = (volatile unsigned char *) rs_table[0].port;
+       //com_port = (volatile unsigned char *) rs_table[1].port;  //jackl
+       com_port_lsr = com_port + UART_LSR;
+
+       while ((c = *s++) != 0)
+               serial_writechar(c);
+
+       /* Most messages don't have a newline in them */
+       serial_writechar('\n');
+       serial_writechar('\r');
+}
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+//REX: 
+void calibrate_decr() {                                                      
+       int freq, divisor;                                                   
+       
+       //jackl system_clock
+       #ifdef SYS_266
+       freq = 133000000;
+       #endif
+       #ifdef SYS_200
+       freq = 100000000;
+       #endif
+       #ifdef SYS_166
+       freq = 66000000;
+       #endif
+       //REX: to avoid slow time!
+       divisor = 4;                                                         
+       tb_ticks_per_jiffy = freq / HZ / divisor;                            
+       tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);             
+}                                                                            
 TODC_ALLOC();
 
 void __init
@@ -681,19 +928,21 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 
        /* Map in board regs, etc. */
        sandpoint_set_bat();
-
+//REX:
+#if 0
        isa_io_base = MPC10X_MAPB_ISA_IO_BASE;
        isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE;
        pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET;
        ISA_DMA_THRESHOLD = 0x00ffffff;
        DMA_MODE_READ = 0x44;
        DMA_MODE_WRITE = 0x48;
-
+#endif
        ppc_md.setup_arch = sandpoint_setup_arch;
        ppc_md.show_cpuinfo = sandpoint_show_cpuinfo;
-       ppc_md.irq_cannonicalize = sandpoint_irq_cannonicalize;
+       //ppc_md.irq_cannonicalize = sandpoint_irq_cannonicalize;
        ppc_md.init_IRQ = sandpoint_init_IRQ;
-       ppc_md.get_irq = openpic_get_irq;
+       //ppc_md.get_irq = openpic_get_irq;
+       ppc_md.get_irq = sandpoint_get_irq;
        ppc_md.init = sandpoint_init2;
 
        ppc_md.restart = sandpoint_restart;
@@ -702,7 +951,8 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 
        ppc_md.find_end_of_memory = sandpoint_find_end_of_memory;
        ppc_md.setup_io_mappings = sandpoint_map_io;
-
+       ppc_md.calibrate_decr = calibrate_decr;
+#ifdef REX_TODC
        TODC_INIT(TODC_TYPE_PC97307, 0x70, 0x00, 0x71, 8);
        ppc_md.time_init = todc_time_init;
        ppc_md.set_rtc_time = todc_set_rtc_time;
@@ -711,10 +961,12 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 
        ppc_md.nvram_read_val = todc_mc146818_read_val;
        ppc_md.nvram_write_val = todc_mc146818_write_val;
+#endif
 
 #ifdef CONFIG_SERIAL
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
-       ppc_md.progress = gen550_progress;
+       //ppc_md.progress = gen550_progress;
+       ppc_md.progress = sandpoint_progress;
 #endif
        ppc_md.early_serial_map = sandpoint_early_serial_map;
 #endif
index 11fcd2a..db59827 100644 (file)
 #define __ASMPPC_SANDPOINT_SERIAL_H
 
 #include <linux/config.h>
-
+#if 0
 #define SANDPOINT_SERIAL_0             0xfe0003f8
 #define SANDPOINT_SERIAL_1             0xfe0002f8
+#endif //REX:
+
+//jackl
+#define TWO_CONSOLE 1
+//#define      CPU_266 1
+#define        CPU_200 1
+//#define      CPU_166 1
+
+//jackl add
+#define UART0_INT      121\r
+#define UART1_INT      122
+//jackl end
+
+#define SANDPOINT_SERIAL_0 0xFC004500
+#define SANDPOINT_SERIAL_1 0xFC004600  //jackl
 
 #ifdef CONFIG_SERIAL_MANY_PORTS
-#define RS_TABLE_SIZE  64
+#define RS_TABLE_SIZE  2       //64    jackl
 #else
-#define RS_TABLE_SIZE  2
+#define RS_TABLE_SIZE 
 #endif
 
 /* Rate for the 1.8432 Mhz clock for the onboard serial chip */
-#define BASE_BAUD ( 1843200 / 16 )
+//#define BASE_BAUD ( 1843200 / 16 )
+//REX:
+
+//jackl+
+#ifdef CPU_266
+#define BASE_BAUD (133000000/16)
+#endif
+#ifdef CPU_200
+#define BASE_BAUD (100000000/16)
+#endif
+#ifdef CPU_166
+#define BASE_BAUD (66000000/16)
+#endif
+//jackl end
 
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
+#else
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
+#endif
+
+//jackl+
+#ifndef TWO_CONSOLE
 #define STD_SERIAL_PORT_DFNS \
-       /* ttyS0 */                                                     \
-        { 0, BASE_BAUD, SANDPOINT_SERIAL_0, 4, ASYNC_BOOT_AUTOCONF,    \
-               iomem_base: (u8 *)SANDPOINT_SERIAL_0,                   \
-               io_type: SERIAL_IO_MEM },                               \
-       /* ttyS1 */                                                     \
-        { 0, BASE_BAUD, SANDPOINT_SERIAL_1, 3, ASYNC_BOOT_AUTOCONF,    \
-               iomem_base: (u8 *)SANDPOINT_SERIAL_1,                   \
-               io_type: SERIAL_IO_MEM },
+        { 0, BASE_BAUD, SANDPOINT_SERIAL_0, 121, STD_COM_FLAGS, /* ttyS0 */ \
+               iomem_base: (u8 *)SANDPOINT_SERIAL_0,                     \
+               io_type: SERIAL_IO_MEM },                                
 
 #define SERIAL_PORT_DFNS \
         STD_SERIAL_PORT_DFNS
+#else
+
+#define STD_SERIAL_PORT_DFNS(num) \
+        { 0, BASE_BAUD, SANDPOINT_SERIAL_##num, UART##num##_INT , STD_COM_FLAGS, /* ttyS0 */ \
+               iomem_base: (u8 *)SANDPOINT_SERIAL_##num,                         \
+               io_type: SERIAL_IO_MEM },                                
+
+#define SERIAL_PORT_DFNS \
+        STD_SERIAL_PORT_DFNS(0)        \
+        STD_SERIAL_PORT_DFNS(1)
+#endif        
+//jackl end
 
 #endif /* __ASMPPC_SANDPOINT_SERIAL_H */
index d07364b..e0d74d8 100644 (file)
@@ -116,7 +116,7 @@ static char *serial_revdate = "2001-07-08";
 #ifdef CONFIG_PCI
 #define ENABLE_SERIAL_PCI
 #ifndef CONFIG_SERIAL_SHARE_IRQ
-#define CONFIG_SERIAL_SHARE_IRQ
+//#define CONFIG_SERIAL_SHARE_IRQ
 #endif
 #ifndef CONFIG_SERIAL_MANY_PORTS
 #define CONFIG_SERIAL_MANY_PORTS
@@ -134,14 +134,20 @@ static char *serial_revdate = "2001-07-08";
 #endif
 
 /* Set of debugging defines */
-
+//REX:
 #undef SERIAL_DEBUG_INTR
+//#define SERIAL_DEBUG_INTR 1
 #undef SERIAL_DEBUG_OPEN
 #undef SERIAL_DEBUG_FLOW
 #undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 #undef SERIAL_DEBUG_PCI
 #undef SERIAL_DEBUG_AUTOCONF
 
+//#define SERIAL_DEBUG_AUTOCONF        1
+//#define SERIAL_DEBUG_OPEN    1
+//#define SERIAL_DEBUG_INTR 1
+//#define jack_debug   1
+
 /* Sanity checks */
 
 #ifdef CONFIG_SERIAL_MULTIPORT
@@ -236,9 +242,7 @@ static char *serial_revdate = "2001-07-08";
 #include <asm/irq.h>
 #include <asm/bitops.h>
 
-#if defined(CONFIG_MAC_SERIAL)
-#define SERIAL_DEV_OFFSET      ((_machine == _MACH_prep || _machine == _MACH_chrp) ? 0 : 2)
-#else
+#ifndef SERIAL_DEV_OFFSET
 #define SERIAL_DEV_OFFSET      0
 #endif
 
@@ -248,6 +252,14 @@ static char *serial_revdate = "2001-07-08";
 #define _INLINE_
 #endif
 
+//jackl+
+#define GET_BUTTON 0x54E0              
+static char RevBuf[16]="";
+static int BufCount=0;
+static int Button_Status=0;
+static int Button_ACK = 0;
+//jackl end
+
 static char *serial_name = "Serial driver";
 
 static DECLARE_TASK_QUEUE(tq_serial);
@@ -415,6 +427,8 @@ static inline int serial_paranoia_check(struct async_struct *info,
 
 static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
 {
+       //REX:
+       //printk("I/O type is %d, iomem_base is %X\n", info->io_type, info->iomem_base);
        switch (info->io_type) {
 #ifdef CONFIG_HUB6
        case SERIAL_IO_HUB6:
@@ -573,19 +587,126 @@ static _INLINE_ void receive_chars(struct async_struct *info,
        do {
                if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
                        tty->flip.tqueue.routine((void *) tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               /* no room in flip buffer, discard rx FIFO contents to clear IRQ
-                                * *FIXME* Hardware with auto flow control
-                                * would benefit from leaving the data in the FIFO and
-                                * disabling the rx IRQ until space becomes available.
-                                */
-                               do {
-                                       serial_inp(info, UART_RX);
-                                       icount->overrun++;
-                                       *status = serial_inp(info, UART_LSR);
-                               } while ((*status & UART_LSR_DR) && (max_count-- > 0));
+                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
                                return;         // if TTY_DONT_FLIP is set
+               }
+               ch = serial_inp(info, UART_RX);
+               *tty->flip.char_buf_ptr = ch;
+               icount->rx++;
+               
+#ifdef SERIAL_DEBUG_INTR
+               printk("DR%02x:%02x...", ch, *status);
+#endif
+               *tty->flip.flag_buf_ptr = 0;
+               if (*status & (UART_LSR_BI | UART_LSR_PE |
+                              UART_LSR_FE | UART_LSR_OE)) {
+                       /*
+                        * For statistics only
+                        */
+                       if (*status & UART_LSR_BI) {
+                               *status &= ~(UART_LSR_FE | UART_LSR_PE);
+                               icount->brk++;
+                               /*
+                                * We do the SysRQ and SAK checking
+                                * here because otherwise the break
+                                * may get masked by ignore_status_mask
+                                * or read_status_mask.
+                                */
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+                               if (info->line == sercons.index) {
+                                       if (!break_pressed) {
+                                               break_pressed = jiffies;
+                                               goto ignore_char;
+                                       }
+                                       break_pressed = 0;
+                               }
+#endif
+                               if (info->flags & ASYNC_SAK)
+                                       do_SAK(tty);
+                       } else if (*status & UART_LSR_PE)
+                               icount->parity++;
+                       else if (*status & UART_LSR_FE)
+                               icount->frame++;
+                       if (*status & UART_LSR_OE)
+                               icount->overrun++;
+
+                       /*
+                        * Mask off conditions which should be ignored.
+                        */
+                       *status &= info->read_status_mask;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+                       if (info->line == sercons.index) {
+                               /* Recover the break flag from console xmit */
+                               *status |= lsr_break_flag;
+                               lsr_break_flag = 0;
+                       }
+#endif
+                       if (*status & (UART_LSR_BI)) {
+#ifdef SERIAL_DEBUG_INTR
+                               printk("handling break....");
+#endif
+                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                       } else if (*status & UART_LSR_PE)
+                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                       else if (*status & UART_LSR_FE)
+                               *tty->flip.flag_buf_ptr = TTY_FRAME;
+               }
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+               if (break_pressed && info->line == sercons.index) {
+                       if (ch != 0 &&
+                           time_before(jiffies, break_pressed + HZ*5)) {
+                               handle_sysrq(ch, regs, NULL, NULL);
+                               break_pressed = 0;
+                               goto ignore_char;
                        }
+                       break_pressed = 0;
+               }
+#endif
+               if ((*status & info->ignore_status_mask) == 0) {
+                       tty->flip.flag_buf_ptr++;
+                       tty->flip.char_buf_ptr++;
+                       tty->flip.count++;
+               }
+               if ((*status & UART_LSR_OE) &&
+                   (tty->flip.count < TTY_FLIPBUF_SIZE)) {
+                       /*
+                        * Overrun is special, since it's reported
+                        * immediately, and doesn't affect the current
+                        * character
+                        */
+                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
+                       tty->flip.count++;
+                       tty->flip.flag_buf_ptr++;
+                       tty->flip.char_buf_ptr++;
+               }
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+       ignore_char:
+#endif
+               *status = serial_inp(info, UART_LSR);
+       } while ((*status & UART_LSR_DR) && (max_count-- > 0));
+#if (LINUX_VERSION_CODE > 131394) /* 2.1.66 */
+       tty_flip_buffer_push(tty);
+#else
+       queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
+#endif 
+}
+
+//jackl+ for ttyS1
+static _INLINE_ void receive_chars1(struct async_struct *info,
+                                int *status, struct pt_regs * regs)
+{
+       struct tty_struct *tty = info->tty;
+       unsigned char ch;
+       struct  async_icount *icount;
+       int     max_count = 256;
+
+       icount = &info->state->icount;
+       do {
+               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+                       tty->flip.tqueue.routine((void *) tty);
+                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+                               return;         // if TTY_DONT_FLIP is set
                }
                ch = serial_inp(info, UART_RX);
                *tty->flip.char_buf_ptr = ch;
@@ -594,6 +715,119 @@ static _INLINE_ void receive_chars(struct async_struct *info,
 #ifdef SERIAL_DEBUG_INTR
                printk("DR%02x:%02x...", ch, *status);
 #endif
+       //printk("Rch=%x\n",ch);
+               if( ( ch!= 0x0a ) && ( ch!= 0x0d ) )
+               {
+                       if ( BufCount < 10 )
+                       {
+                               RevBuf[BufCount]=ch;
+                               BufCount++;
+                       }
+               }
+               else if ( ch == 0x0a )
+               {
+                       //printk("RevBuf= %s\n",RevBuf);
+                       if( ( RevBuf[1]== 'K') && ( RevBuf[2]== 'O') )
+                       {
+                               switch(RevBuf[0])
+                               {
+                                       case 'R':
+                                               Button_Status |= 0x01;
+                                               break;
+                                               
+                                       case 'U':
+                                               Button_Status |= 0x02;
+                                               break;
+                                               
+                                       case 'C':
+                                               Button_Status |= 0x04;
+                                               break;
+                                               
+                                       case 'E':
+                                               Button_Status |= 0x08;
+                                               break;
+                                       
+                                       //jack20050420+
+                                       case 'P':
+                                               Button_Status |= 0x0100;
+                                               break;
+                                       
+                                       case '1':
+                                               Button_Status |= 0x0200;
+                                               break;
+                                                               
+                                       default:
+                                               break;
+                               }
+                       }
+                       else if ( ( RevBuf[0]== 'T') && ( RevBuf[1]== 'S') )
+                       {
+                               switch(RevBuf[2])
+                               {
+                                       case '1':
+                                               Button_Status |= 0x10;
+                                               break;
+                                               
+                                       case '2':
+                                               Button_Status |= 0x20;
+                                               break;
+                                       
+                                       default:
+                                               break;
+                               }
+                       }
+                       else if ( ( RevBuf[1]== 'K') && ( RevBuf[2]== 'R') )
+                       {
+                               switch(RevBuf[0])
+                               {
+                                       case 'R':
+                                               Button_Status |= 0x40;
+                                               break;
+                                               
+                                       case 'U':
+                                               Button_Status |= 0x80;
+                                               break;
+                                       
+                                       default:
+                                               break;
+                               }
+                       }
+                       else if ( ( RevBuf[1]== 'O') && ( RevBuf[2]== 'K') ) //jack20050624+
+                       {
+                               switch(RevBuf[0])
+                               {
+                                       case 'I':
+                                               Button_Status |= 0x1000;
+                                               break;
+                                               
+                                       case 'L':
+                                               Button_Status |= 0x2000;
+                                               break;
+                       
+                                       case 'N':
+                                               Button_Status |= 0x4000;
+                                               break;
+                                       default:
+                                               break;
+                               }
+                       }//jack20050624 end
+                       else if ( ( RevBuf[0]== 'A') && ( RevBuf[1]== 'K') )
+                       {
+                               //jack20051025+
+                               switch(RevBuf[2])
+                               {
+                                       case 'I':
+                                               Button_ACK |= 0x8000;
+                                               break;
+                                       default:
+                                               break;
+                               }
+                               //jack20051025 end
+                       }
+                       memset(RevBuf,0,16);
+                       BufCount=0;
+               }
+               
                *tty->flip.flag_buf_ptr = 0;
                if (*status & (UART_LSR_BI | UART_LSR_PE |
                               UART_LSR_FE | UART_LSR_OE)) {
@@ -688,6 +922,7 @@ static _INLINE_ void receive_chars(struct async_struct *info,
        queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
 #endif 
 }
+//jackl end
 
 static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
 {
@@ -852,7 +1087,7 @@ static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 #endif
                if (status & UART_LSR_DR)
                        receive_chars(info, &status, regs);
-               check_modem_status(info);
+               //check_modem_status(info);
 #ifdef CONFIG_MELAN
                if ((status & UART_LSR_THRE) ||
                        /* for buggy ELAN processors */
@@ -923,17 +1158,19 @@ static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
                printk("status = %x...", status);
 #endif
                if (status & UART_LSR_DR)
-                       receive_chars(info, &status, regs);
+               {
+                       if ( irq == 122)
+                               receive_chars1(info, &status, regs);
+                       else
+                               receive_chars(info, &status, regs);
+               }
                check_modem_status(info);
-#ifdef CONFIG_MELAN
                if ((status & UART_LSR_THRE) ||
                    /* For buggy ELAN processors */
                    ((iir & UART_IIR_ID) == UART_IIR_THRI))
+               {
                        transmit_chars(info, 0);
-#else
-               if (status & UART_LSR_THRE)
-                       transmit_chars(info, 0);
-#endif
+               }
                if (pass_counter++ > RS_ISR_PASS_LIMIT) {
 #if SERIAL_DEBUG_INTR
                        printk("rs_single loop break.\n");
@@ -1068,15 +1305,17 @@ static void do_serial_bh(void)
 static void do_softint(void *private_)
 {
        struct async_struct     *info = (struct async_struct *) private_;
-       struct tty_struct       *tty;
-
+       struct tty_struct       *tty;
+       
        tty = info->tty;
        if (!tty)
                return;
 
        if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-               tty_wakeup(tty);
-               
+               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+                   tty->ldisc.write_wakeup)
+                       (tty->ldisc.write_wakeup)(tty);
+               wake_up_interruptible(&tty->write_wait);
 #ifdef SERIAL_HAVE_POLL_WAIT
                wake_up_interruptible(&tty->poll_wait);
 #endif
@@ -1227,7 +1466,8 @@ static int startup(struct async_struct * info)
 #ifdef CONFIG_SERIAL_MANY_PORTS
        unsigned short ICP;
 #endif
-
+       char buf;
+       
        page = get_zeroed_page(GFP_KERNEL);
        if (!page)
                return -ENOMEM;
@@ -1354,8 +1594,8 @@ static int startup(struct async_struct * info)
        /*
         * Allocate the IRQ if necessary
         */
-       if (state->irq && (!IRQ_ports[state->irq] ||
-                         !IRQ_ports[state->irq]->next_port)) {
+       if (!IRQ_ports[state->irq] ||
+                         !IRQ_ports[state->irq]->next_port) {
                if (IRQ_ports[state->irq]) {
 #ifdef CONFIG_SERIAL_SHARE_IRQ
                        free_irq(state->irq, &IRQ_ports[state->irq]);
@@ -1372,8 +1612,14 @@ static int startup(struct async_struct * info)
                } else 
                        handler = rs_interrupt_single;
 
+               //jackl
+#ifdef CONFIG_SERIAL_SHARE_IRQ         
                retval = request_irq(state->irq, handler, SA_SHIRQ,
                                     "serial", &IRQ_ports[state->irq]);
+#else          
+               retval = request_irq(state->irq, handler, SA_INTERRUPT,
+                                    "serial", &IRQ_ports[state->irq]);
+#endif                              
                if (retval) {
                        if (capable(CAP_SYS_ADMIN)) {
                                if (info->tty)
@@ -1398,9 +1644,17 @@ static int startup(struct async_struct * info)
        /*
         * Now, initialize the UART 
         */
-       serial_outp(info, UART_LCR, UART_LCR_WLEN8);    /* reset DLAB */
-
-       info->MCR = 0;
+//     if (info->line == 1)
+//     {
+//             serial_outp(info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_STOP );
+//     }       
+//     else
+//     {
+               serial_outp(info, UART_LCR, UART_LCR_WLEN8);    /* reset DLAB */
+//     }
+
+//jack+        
+       info->MCR = 0;  
        if (info->tty->termios->c_cflag & CBAUD)
                info->MCR = UART_MCR_DTR | UART_MCR_RTS;
 #ifdef CONFIG_SERIAL_MANY_PORTS
@@ -1410,11 +1664,12 @@ static int startup(struct async_struct * info)
        } else
 #endif
        {
-               if (state->irq != 0)
+               if ((state->irq != 0) && (state->irq == 121))
                        info->MCR |= UART_MCR_OUT2;
        }
        info->MCR |= ALPHA_KLUDGE_MCR;          /* Don't ask */
        serial_outp(info, UART_MCR, info->MCR);
+//jack end
        
        /*
         * Finally, enable interrupts
@@ -1471,6 +1726,12 @@ static int startup(struct async_struct * info)
 
        info->flags |= ASYNC_INITIALIZED;
        restore_flags(flags);
+       
+       if (info->line == 1)
+       {
+               buf = serial_inp(info, 2);
+               serial_outp(info, 2, buf);
+       }
        return 0;
        
 errout:
@@ -1520,14 +1781,20 @@ static void shutdown(struct async_struct * info)
        /*
         * Free the IRQ, if necessary
         */
-       if (state->irq && (!IRQ_ports[state->irq] ||
+       if ((!IRQ_ports[state->irq] ||
                          !IRQ_ports[state->irq]->next_port)) {
                if (IRQ_ports[state->irq]) {
                        free_irq(state->irq, &IRQ_ports[state->irq]);
+//jackl
+#ifdef CONFIG_SERIAL_SHARE_IRQ 
                        retval = request_irq(state->irq, rs_interrupt_single,
                                             SA_SHIRQ, "serial",
                                             &IRQ_ports[state->irq]);
-                       
+#else                                       
+                       retval = request_irq(state->irq, rs_interrupt_single,
+                                            SA_INTERRUPT, "serial",
+                                            &IRQ_ports[state->irq]);
+#endif                 
                        if (retval)
                                printk("serial shutdown: request_irq: error %d"
                                       "  Couldn't reacquire IRQ.\n", retval);
@@ -1543,6 +1810,7 @@ static void shutdown(struct async_struct * info)
 
        info->IER = 0;
        serial_outp(info, UART_IER, 0x00);      /* disable all intrs */
+//jack 
 #ifdef CONFIG_SERIAL_MANY_PORTS
        if (info->flags & ASYNC_FOURPORT) {
                /* reset interrupts on the AST Fourport board */
@@ -1552,10 +1820,12 @@ static void shutdown(struct async_struct * info)
 #endif
                info->MCR &= ~UART_MCR_OUT2;
        info->MCR |= ALPHA_KLUDGE_MCR;          /* Don't ask */
+//jack end
        
        /* disable break condition */
        serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
-       
+
+//jack 
        if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
                info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
        serial_outp(info, UART_MCR, info->MCR);
@@ -1643,6 +1913,10 @@ static void change_speed(struct async_struct *info,
        int     bits;
        unsigned long   flags;
 
+#ifdef jack_debug      
+       printk("change_speed info->line = %d\n",info->line);
+#endif
+       
        if (!info->tty || !info->tty->termios)
                return;
        cflag = info->tty->termios->c_cflag;
@@ -1666,8 +1940,10 @@ static void change_speed(struct async_struct *info,
                cval |= UART_LCR_PARITY;
                bits++;
        }
+       
        if (!(cflag & PARODD))
                cval |= UART_LCR_EPAR;
+
 #ifdef CMSPAR
        if (cflag & CMSPAR)
                cval |= UART_LCR_SPAR;
@@ -1827,20 +2103,21 @@ static void change_speed(struct async_struct *info,
 
 static void rs_put_char(struct tty_struct *tty, unsigned char ch)
 {
-       struct async_struct *info;
+       struct async_struct *info = (struct async_struct *)tty->driver_data;
        unsigned long flags;
 
-       if (!tty)
-               return;
-       
-       info =  (struct async_struct *)tty->driver_data;
-       
        if (serial_paranoia_check(info, tty->device, "rs_put_char"))
                return;
 
-       if (!info->xmit.buf)
+       if (!tty || !info->xmit.buf)
                return;
-
+//jack20051025+
+       if (info->line == 1)
+       {
+               if ( ch == 0x0d )
+                       return;
+       }
+//jack20051025 end
        save_flags(flags); cli();
        if (CIRC_SPACE(info->xmit.head,
                       info->xmit.tail,
@@ -1849,6 +2126,12 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch)
                return;
        }
 
+       //jackl+
+#ifdef jack_debug      
+       if (info->line == 1)
+               printk("ch = %02x\n",ch);
+#endif
+               
        info->xmit.buf[info->xmit.head] = ch;
        info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
        restore_flags(flags);
@@ -1878,18 +2161,13 @@ static int rs_write(struct tty_struct * tty, int from_user,
                    const unsigned char *buf, int count)
 {
        int     c, ret = 0;
-       struct async_struct *info;
+       struct async_struct *info = (struct async_struct *)tty->driver_data;
        unsigned long flags;
                                
-       if (!tty)
-               return 0;
-
-       info = (struct async_struct *)tty->driver_data;
-       
        if (serial_paranoia_check(info, tty->device, "rs_write"))
                return 0;
 
-       if (!info->xmit.buf || !tmp_buf)
+       if (!tty || !info->xmit.buf || !tmp_buf)
                return 0;
 
        save_flags(flags);
@@ -1984,10 +2262,13 @@ static void rs_flush_buffer(struct tty_struct *tty)
        save_flags(flags); cli();
        info->xmit.head = info->xmit.tail = 0;
        restore_flags(flags);
+       wake_up_interruptible(&tty->write_wait);
 #ifdef SERIAL_HAVE_POLL_WAIT
        wake_up_interruptible(&tty->poll_wait);
 #endif
-       tty_wakeup(tty);
+       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+           tty->ldisc.write_wakeup)
+               (tty->ldisc.write_wakeup)(tty);
 }
 
 /*
@@ -2019,6 +2300,8 @@ static void rs_send_xchar(struct tty_struct *tty, char ch)
  */
 static void rs_throttle(struct tty_struct * tty)
 {
+//jackl+       
+#if 0  
        struct async_struct *info = (struct async_struct *)tty->driver_data;
        unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
@@ -2040,10 +2323,13 @@ static void rs_throttle(struct tty_struct * tty)
        save_flags(flags); cli();
        serial_out(info, UART_MCR, info->MCR);
        restore_flags(flags);
+#endif
+//jackl end
 }
 
 static void rs_unthrottle(struct tty_struct * tty)
 {
+#if 0  
        struct async_struct *info = (struct async_struct *)tty->driver_data;
        unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
@@ -2067,6 +2353,7 @@ static void rs_unthrottle(struct tty_struct * tty)
        save_flags(flags); cli();
        serial_out(info, UART_MCR, info->MCR);
        restore_flags(flags);
+#endif
 }
 
 /*
@@ -2546,9 +2833,14 @@ static int set_multiport_struct(struct async_struct * info,
                        handler = rs_interrupt_multi;
                else
                        handler = rs_interrupt;
-
+//jackl
+#ifdef CONFIG_SERIAL_SHARE_IRQ 
                retval = request_irq(state->irq, handler, SA_SHIRQ,
                                     "serial", &IRQ_ports[state->irq]);
+#else                               
+               retval = request_irq(state->irq, handler, SA_INTERRUPT,
+                                    "serial", &IRQ_ports[state->irq]);
+#endif                                 
                if (retval) {
                        printk("Couldn't reallocate serial interrupt "
                               "driver!!\n");
@@ -2565,6 +2857,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
        struct async_icount cprev, cnow;        /* kernel counter temps */
        struct serial_icounter_struct icount;
        unsigned long flags;
+       int status=0;
 #if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
        int retval, tmp;
 #endif
@@ -2619,24 +2912,26 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
                                 (tmp ? CLOCAL : 0));
                        return 0;
 #endif
-               case TIOCMGET:
-                       return get_modem_info(info, (unsigned int *) arg);
+//jackl+
+//             case TIOCMGET:
+//                     return get_modem_info(info, (unsigned int *) arg);
                case TIOCMBIS:
                case TIOCMBIC:
-               case TIOCMSET:
-                       return set_modem_info(info, cmd, (unsigned int *) arg);
+//             case TIOCMSET:
+//                     return set_modem_info(info, cmd, (unsigned int *) arg);
                case TIOCGSERIAL:
                        return get_serial_info(info,
                                               (struct serial_struct *) arg);
-               case TIOCSSERIAL:
-                       return set_serial_info(info,
-                                              (struct serial_struct *) arg);
-               case TIOCSERCONFIG:
-                       return do_autoconfig(info);
-
-               case TIOCSERGETLSR: /* Get line status register */
-                       return get_lsr_info(info, (unsigned int *) arg);
-
+//jackl+                                              
+//             case TIOCSSERIAL:
+//                     return set_serial_info(info,
+//                                            (struct serial_struct *) arg);
+//             case TIOCSERCONFIG:
+//                     return do_autoconfig(info);
+//
+//             case TIOCSERGETLSR: /* Get line status register */
+//                     return get_lsr_info(info, (unsigned int *) arg);
+//jackl end
                case TIOCSERGSTRUCT:
                        if (copy_to_user((struct async_struct *) arg,
                                         info, sizeof(struct async_struct)))
@@ -2659,6 +2954,8 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
                 * Caller should use TIOCGICOUNT to see which one it was
                 */
                case TIOCMIWAIT:
+//jackl+               
+#if 0          
                        save_flags(flags); cli();
                        /* note the counters on entry */
                        cprev = info->state->icount;
@@ -2686,7 +2983,8 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
                                cprev = cnow;
                        }
                        /* NOTREACHED */
-
+#endif
+//jackl end
                /* 
                 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
                 * Return: write counters to the user passed counter struct
@@ -2717,7 +3015,19 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
                        /* "setserial -W" is called in Debian boot */
                        printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
                        return 0;
-
+               
+               case GET_BUTTON:
+                       status = Button_Status;
+                       Button_Status = 0;
+                       return status;
+                       
+               //jack20051025+
+               case GET_BUTTON+1:
+                       status = Button_ACK&0x00008000;
+                       Button_ACK &= 0xffff7fff;
+                       return status;
+               //jack20051025 end
+               
                default:
                        return -ENOIOCTLCMD;
                }
@@ -2726,6 +3036,8 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
 
 static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
 {
+//jackl+       
+#if 0  
        struct async_struct *info = (struct async_struct *)tty->driver_data;
        unsigned long flags;
        unsigned int cflag = tty->termios->c_cflag;
@@ -2777,6 +3089,8 @@ static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
            (tty->termios->c_cflag & CLOCAL))
                wake_up_interruptible(&info->open_wait);
 #endif
+#endif
+//jackl end
 }
 
 /*
@@ -2850,8 +3164,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
         * the line discipline to only process XON/XOFF characters.
         */
        tty->closing = 1;
-       if (state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-               tty_wait_until_sent(tty, state->closing_wait);
+       if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+               tty_wait_until_sent(tty, info->closing_wait);
        /*
         * At this point we stop accepting input.  To do this, we
         * disable the receive line status interrupts, and tell the
@@ -2872,14 +3186,15 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
        shutdown(info);
        if (tty->driver.flush_buffer)
                tty->driver.flush_buffer(tty);
-       tty_ldisc_flush(tty);
+       if (tty->ldisc.flush_buffer)
+               tty->ldisc.flush_buffer(tty);
        tty->closing = 0;
        info->event = 0;
        info->tty = 0;
        if (info->blocked_open) {
-               if (state->close_delay) {
+               if (info->close_delay) {
                        set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(state->close_delay);
+                       schedule_timeout(info->close_delay);
                }
                wake_up_interruptible(&info->open_wait);
        }
@@ -2985,6 +3300,8 @@ static void rs_hangup(struct tty_struct *tty)
 static int block_til_ready(struct tty_struct *tty, struct file * filp,
                           struct async_struct *info)
 {
+//jackl+
+#if 0  
        DECLARE_WAITQUEUE(wait, current);
        struct serial_state *state = info->state;
        int             retval;
@@ -3114,6 +3431,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
        if (retval)
                return retval;
        info->flags |= ASYNC_NORMAL_ACTIVE;
+#endif
+//jackl end    
        return 0;
 }
 
@@ -3175,6 +3494,11 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
 
        MOD_INC_USE_COUNT;
        line = MINOR(tty->device) - tty->driver.minor_start;
+
+#ifdef jack_debug      
+       printk("device=%d,minor_start=%d,line = %d\n",MINOR(tty->device),tty->driver.minor_start,line);
+#endif
+       
        if ((line < 0) || (line >= NR_PORTS)) {
                MOD_DEC_USE_COUNT;
                return -ENODEV;
@@ -3228,18 +3552,25 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
        /*
         * Start up serial port
         */
+//jackl+
+       if ( info->line == 1 )
+               serial_outp(info, 0x11, 1 );
+//jackl end
+               
        retval = startup(info);
        if (retval)
                return retval;
 
-       retval = block_til_ready(tty, filp, info);
-       if (retval) {
-#ifdef SERIAL_DEBUG_OPEN
-               printk("rs_open returning after block_til_ready with %d\n",
-                      retval);
-#endif
-               return retval;
-       }
+//jack+
+//     retval = block_til_ready(tty, filp, info);
+//     if (retval) {
+//#ifdef SERIAL_DEBUG_OPEN
+//             printk("rs_open returning after block_til_ready with %d\n",
+//                    retval);
+//#endif
+//             return retval;
+//     }
+//jackl end
 
        if ((info->state->count == 1) &&
            (info->flags & ASYNC_SPLIT_TERMIOS)) {
@@ -3271,6 +3602,7 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
 
 static inline int line_info(char *buf, struct serial_state *state)
 {
+#if 0  
        struct async_struct *info = state->info, scr_info;
        char    stat_buf[30], control, status;
        int     ret;
@@ -3349,6 +3681,8 @@ static inline int line_info(char *buf, struct serial_state *state)
         */
        ret += sprintf(buf+ret, " %s\n", stat_buf+1);
        return ret;
+#endif
+       return 0;       
 }
 
 static int rs_read_proc(char *page, char **start, off_t off, int count,
@@ -3761,14 +4095,7 @@ static void autoconfig(struct serial_state * state)
                /* Check for Startech UART's */
                serial_outp(info, UART_LCR, UART_LCR_DLAB);
                if (serial_in(info, UART_EFR) == 0) {
-                       serial_outp(info, UART_EFR, 0xA8);
-                       if (serial_in(info, UART_EFR) == 0) {
-                               /* We are a NS16552D/Motorola
-                                * 8xxx DUART, stop. */
-                               goto out;
-                       }
                        state->type = PORT_16650;
-                       serial_outp(info, UART_EFR, 0);
                } else {
                        serial_outp(info, UART_LCR, 0xBF);
                        if (serial_in(info, UART_EFR) == 0)
@@ -3817,7 +4144,6 @@ static void autoconfig(struct serial_state * state)
                }
        }
 #endif
-out:
        serial_outp(info, UART_LCR, save_lcr);
        if (state->type == PORT_16450) {
                scratch = serial_in(info, UART_SCR);
@@ -4212,10 +4538,10 @@ pci_inteli960ni_fn(struct pci_dev *dev,
        if (!enable) /* is there something to deinit? */
                return(0);
    
-#ifdef SERIAL_DEBUG_PCI
-       printk(KERN_DEBUG " Subsystem ID %lx (intel 960)\n",
-              (unsigned long) board->subdevice);
-#endif
+//#ifdef SERIAL_DEBUG_PCI
+//     printk(KERN_DEBUG " Subsystem ID %lx (intel 960)\n",
+//            (unsigned long) board->subdevice);
+//#endif
        /* is firmware started? */
        pci_read_config_dword(dev, 0x44, (void*) &oldval); 
        if (oldval == 0x00001000L) { /* RESET value */ 
@@ -4381,10 +4707,9 @@ enum pci_board_num_t {
 #ifdef CONFIG_DDB5074
        pbn_nec_nile4,
 #endif
-
-       pbn_dci_pccom4,
+#if 0
        pbn_dci_pccom8,
-
+#endif
        pbn_xircom_combo,
 
        pbn_siig10x_0,
@@ -4478,10 +4803,9 @@ static struct pci_board pci_boards[] __devinitdata = {
        { SPCI_FL_BASE0, 1, 520833,                        /* pbn_nec_nile4 */
                64, 3, NULL, 0x300 },
 #endif
-
-       {SPCI_FL_BASE3, 4, 115200, 8},                     /* pbn_dci_pccom4 */
-       {SPCI_FL_BASE3, 8, 115200, 8},                     /* pbn_dci_pccom8 */
-
+#if 0  /* PCI_DEVICE_ID_DCI_PCCOM8 ? */                   /* pbn_dci_pccom8 */
+       { SPCI_FL_BASE3, 8, 115200, 8 },
+#endif
        { SPCI_FL_BASE0, 1, 115200,                       /* pbn_xircom_combo */
                0, 0, pci_xircom_fn },
 
@@ -4558,6 +4882,10 @@ static int __devinit serial_init_one(struct pci_dev *dev,
        struct pci_board *board, tmp;
        int rc;
 
+#ifdef jack_debug      
+       printk("serial_init_one\n");
+#endif
+       
        board = &pci_boards[ent->driver_data];
 
        rc = pci_enable_device(dev);
@@ -4942,12 +5270,11 @@ static struct pci_device_id serial_pci_tbl[] __devinitdata = {
                pbn_nec_nile4 },
 #endif
 
-       {       PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM4,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               pbn_dci_pccom4 },
+#if 0  /* PCI_DEVICE_ID_DCI_PCCOM8 ? */
        {       PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
                pbn_dci_pccom8 },
+#endif
 
        { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
         PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, },
@@ -5468,7 +5795,8 @@ static int __init rs_init(void)
        serial_driver.subtype = SERIAL_TYPE_NORMAL;
        serial_driver.init_termios = tty_std_termios;
        serial_driver.init_termios.c_cflag =
-               B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+               B9600 | CS8 | HUPCL;                                    //jackl+
+       //      B9600 | CS8 | CREAD | HUPCL | CLOCAL;   //jackl+
        serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
        serial_driver.refcount = &serial_refcount;
        serial_driver.table = serial_table;
@@ -5524,6 +5852,9 @@ static int __init rs_init(void)
        for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
                state->magic = SSTATE_MAGIC;
                state->line = i;
+#ifdef jack_debug              
+               printk("state->line=%d\n",state->line);
+#endif         
                state->type = PORT_UNKNOWN;
                state->custom_divisor = 0;
                state->close_delay = 5*HZ/10;
@@ -5545,7 +5876,9 @@ static int __init rs_init(void)
                        continue;
 #endif                 
                if (state->flags & ASYNC_BOOT_AUTOCONF)
+               {
                        autoconfig(state);
+               }
        }
        for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
                if (state->type == PORT_UNKNOWN)
@@ -5555,7 +5888,7 @@ static int __init rs_init(void)
                    && (state->port != 0 || state->iomem_base != 0))
                        state->irq = detect_uart_irq(state);
                if (state->io_type == SERIAL_IO_MEM) {
-                       printk(KERN_INFO"ttyS%02d%s at 0x%p (irq = %d) is a %s\n",
+                       printk(KERN_INFO"ttyS%02d%s at 0x%p (IOMEM)(irq = %d) is a %s\n",
                               state->line + SERIAL_DEV_OFFSET,
                               (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
                               state->iomem_base, state->irq,
@@ -5638,7 +5971,8 @@ int register_serial(struct serial_struct *req)
        struct serial_state *state;
        struct async_struct *info;
        unsigned long port;
-
+       
+       printk("register_serial\n");
        port = req->port;
        if (HIGH_BITS_OFFSET)
                port += (unsigned long) req->port_high << HIGH_BITS_OFFSET;
@@ -5859,7 +6193,7 @@ static void serial_console_write(struct console *co, const char *s,
        static struct async_struct *info = &async_sercons;
        int ier;
        unsigned i;
-
+       
        /*
         *      First save the IER then disable the interrupts
         */
@@ -5915,6 +6249,9 @@ static int __init serial_console_setup(struct console *co, char *options)
        int     quot = 0;
        char    *s;
 
+#ifdef jack_debug
+       printk("serial_console_setup\n");
+#endif 
        if (options) {
                baud = simple_strtoul(options, NULL, 10);
                s = options;
@@ -6004,6 +6341,7 @@ static int __init serial_console_setup(struct console *co, char *options)
 #endif /* !__powerpc__ && !__alpha__ */
        if (cflag & PARENB)
                cval |= UART_LCR_PARITY;
+               
        if (!(cflag & PARODD))
                cval |= UART_LCR_EPAR;
 
@@ -6016,7 +6354,7 @@ static int __init serial_console_setup(struct console *co, char *options)
        serial_out(info, UART_DLM, quot >> 8);          /* MS of divisor */
        serial_out(info, UART_LCR, cval);               /* reset DLAB */
        serial_out(info, UART_IER, 0);
-       serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
+       serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);        //jack
 
        /*
         *      If we read 0xff from the LSR, there is no UART here.
@@ -6045,6 +6383,31 @@ void __init serial_console_init(void)
 }
 #endif
 
+#ifdef jack_debug
+static void show_serial_info(void)
+{
+       int i;
+       printk("EPIC DURAT re1 %08x\n",le32_to_cpu((*((volatile unsigned long *)(0xfc051120))))  );
+       printk("EPIC DURAT re2 %08x\n",le32_to_cpu((*((volatile unsigned long *)(0xfc051130))))  );
+       printk("EPIC DURAT re3 %08x\n",le32_to_cpu((*((volatile unsigned long *)(0xfc051140))))  );
+       printk("EPIC DURAT re4 %08x\n",le32_to_cpu((*((volatile unsigned long *)(0xfc051150))))  );
+       printk("\n");
+       for (i=0;i<10;i++)
+       {
+               printk("DURAT1 re0x%d=%02x\n",i,(*((volatile char *)(0xfc004500+i)))&0xff  );
+       }
+       printk("DURAT1 re0x10=%02x\n",(*((volatile char *)(0xfc004510)))&0xff  );
+       printk("DURAT1 re0x11=%02x\n",(*((volatile char *)(0xfc004511)))&0xff  );
+       printk("\n");
+       for (i=0;i<10;i++)
+       {
+               printk("DURAT2 re0x%d=%02x\n",i,(*((volatile char *)(0xfc004600+i)))&0xff  );
+       }
+       printk("DURAT1 re0x10=%02x\n",(*((volatile char *)(0xfc004610)))&0xff  );
+       printk("DURAT1 re0x11=%02x\n",(*((volatile char *)(0xfc004611)))&0xff  );
+       printk("*********************\n");
+}
+#endif
 /*
   Local variables:
   compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h   -DEXPORT_SYMTAB -c serial.c"
index b4d8aa9..57c54bb 100644 (file)
@@ -2647,7 +2647,7 @@ void __init console_init(void)
        memcpy(tty_std_termios.c_cc, INIT_C_CC, NCCS);
        tty_std_termios.c_iflag = ICRNL | IXON;
        tty_std_termios.c_oflag = OPOST | ONLCR;
-       tty_std_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL;
+       tty_std_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
        tty_std_termios.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
                ECHOCTL | ECHOKE | IEXTEN;
 
index 942d6f1..88233c4 100644 (file)
@@ -61,7 +61,9 @@ extern inline int openpic_to_irq(int irq)
         * shouldn't use openpic_to_irq
         */
        if (irq != 0){
-               return irq += NUM_8259_INTERRUPTS;
+               //REX:
+               //return irq += NUM_8259_INTERRUPTS;
+               return irq;
        } else {
                return 0;
        }