罗伟提交fpga gpio接口修改
authorroot <root@dxj-desktop.(none)>
Tue, 10 Aug 2010 06:42:39 +0000 (14:42 +0800)
committerroot <root@dxj-desktop.(none)>
Tue, 10 Aug 2010 07:24:41 +0000 (15:24 +0800)
arch/arm/mach-rk2818/include/mach/spi_fpga.h
drivers/fpga/spi_gpio.c

index bb58ed2ff63f2b360aa95c24080b452785e4f4de..1b7c4a057074620afc3da3f1ea40962dd40f0a64 100755 (executable)
@@ -4,12 +4,14 @@ defines of FPGA chip ICE65L08's register
 \r
 #ifndef SPI_UART_H\r
 #define SPI_UART_H\r
+\r
 #include <linux/circ_buf.h>\r
 #include <linux/miscdevice.h>\r
 \r
 #define SPI_FPGA_INT_PIN RK2818_PIN_PA4\r
 #define SPI_DPRAM_BUSY_PIN RK2818_PIN_PA2\r
 #define SPI_FPGA_STANDBY_PIN RK2818_PIN_PH7\r
+#define SPI_FPGA_RST_PIN RK2818_PIN_PH6\r
 \r
 #define SPI_FPGA_TEST_DEBUG    0\r
 #if SPI_FPGA_TEST_DEBUG\r
@@ -60,7 +62,10 @@ struct spi_gpio
 {\r
        struct workqueue_struct         *spi_gpio_workqueue;\r
        struct work_struct      spi_gpio_work;\r
+       struct workqueue_struct         *spi_gpio_irq_workqueue;\r
+       struct work_struct      spi_gpio_irq_work;\r
        struct timer_list       gpio_timer;\r
+       struct list_head        msg_queue;\r
 \r
 };\r
 struct spi_i2c_data\r
index 3df06448b53881bee3f7fc4fe5c1cb9d4db480d9..c7306456b5f49d18729091c58aff5ac2941666b7 100755 (executable)
@@ -38,7 +38,6 @@
 \r
 #define SPI_GPIO_TEST 0\r
 #define HIGH_SPI_TEST 1\r
-#define USE_SYS_INT      0\r
 \r
 spinlock_t             gpio_lock;\r
 spinlock_t             gpio_state_lock;\r
@@ -278,11 +277,11 @@ eSpiGpioPinLevel_t spi_gpio_get_pinlevel(eSpiGpioPinNum_t PinNum)
        if(ICE_SEL_GPIO0 == reg)\r
        {\r
                reg |= ICE_SEL_GPIO0_DATA;\r
-               if((state & (1 << PinNum )) != 0)\r
-               {\r
-                       printk("Fail to get PinLevel because it is int pin!\n");\r
-                       return SPI_GPIO_LEVEL_ERR;\r
-               }       \r
+               //if((state & (1 << PinNum )) != 0)\r
+               //{\r
+               //      printk("Fail to get PinLevel because it is int pin!\n");\r
+               //      return SPI_GPIO_LEVEL_ERR;\r
+               //}     \r
                ret = spi_gpio_read_reg(reg);   \r
        }\r
        else\r
@@ -411,6 +410,7 @@ int spi_gpio_read_iir(void)
 \r
 int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiGpioIntType_t IntType,void *dev_id)\r
 {                      \r
+#if 0\r
        if(PinNum >= SPI_GPIO_IRQ_NUM)\r
        return -1;\r
        DBG("Enter::%s,LINE=%d,PinNum=%d\n",__FUNCTION__,__LINE__,PinNum);\r
@@ -439,7 +439,7 @@ int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiGpioIntT
                printk("%s err:fail to enable gpio intterupt when PinNum=%d\n",__FUNCTION__,PinNum);\r
                return -1;\r
        }\r
-       \r
+#endif \r
        return 0;\r
 }\r
 \r
@@ -454,38 +454,7 @@ int spi_free_gpio_irq(eSpiGpioPinNum_t PinNum)
        return 0;\r
 }\r
        \r
-#if (USE_SYS_INT ==0)\r
-int spi_gpio_handle_irq(struct spi_device *spi)\r
-{\r
-       int gpio_iir, i;\r
-       int state;\r
-       spin_lock(&gpio_state_lock);\r
-       state = gGpio0State;\r
-       spin_unlock(&gpio_state_lock);\r
-\r
-       gpio_iir = spi_gpio_read_iir() & 0xffff;        \r
-       if(gpio_iir == 0xffff)\r
-               return -1;\r
-\r
-       DBG("gpio_iir=0x%x\n",gpio_iir);\r
-       for(i=0; i<SPI_GPIO_IRQ_NUM; i++)\r
-       {\r
-               if(((gpio_iir & (1 << i)) == 0) && ((state & (1 << i)) != 0))\r
-               {\r
-                       if(g_spiGpioVectorTable[i].gpio_vector)\r
-                       {\r
-                               spin_lock(&gpio_irq_lock);\r
-                               g_spiGpioVectorTable[i].gpio_vector(i,g_spiGpioVectorTable[i].gpio_devid);\r
-                               spin_unlock(&gpio_irq_lock);\r
-                               DBG("%s:spi_gpio_irq=%d\n",__FUNCTION__,i);\r
-                       }\r
-               }                       \r
-       }       \r
 \r
-       return  0;\r
-\r
-}\r
-#else\r
 int spi_gpio_handle_irq(struct spi_device *spi)\r
 {\r
        int gpio_iir, i;\r
@@ -516,7 +485,7 @@ int spi_gpio_handle_irq(struct spi_device *spi)
        return  0;\r
 \r
 }\r
-#endif\r
+\r
 \r
 #if SPI_GPIO_TEST\r
 static irqreturn_t spi_gpio_int_test_0(int irq, void *dev)\r
@@ -568,24 +537,6 @@ void spi_gpio_work_handler(struct work_struct *work)
        }\r
 \r
 #elif (FPGA_TYPE == ICE_CC196)\r
-#if 0\r
-       for(i=16;i<81;i++)\r
-       {\r
-               spi_gpio_set_pinlevel(i, TestGpioPinLevel);\r
-               ret = spi_gpio_get_pinlevel(i);\r
-               if(ret != TestGpioPinLevel)\r
-               {\r
-                       #if SPI_FPGA_TEST_DEBUG\r
-                       spi_test_wrong_handle();\r
-                       #endif\r
-                       printk("err:PinNum=%d,set_pinlevel=%d but get_pinlevel=%d\n",i,TestGpioPinLevel,ret);   \r
-                       ret = spi_gpio_get_pindirection(i);\r
-                       printk("spi_gpio_get_pindirection=%d\n\n",ret);\r
-               }\r
-       }\r
-\r
-       DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
-#else\r
        for(i=4;i<81;i++)\r
        {\r
                gpio_direction_output(GPIOS_EXPANDER_BASE+i,TestGpioPinLevel);\r
@@ -607,10 +558,6 @@ void spi_gpio_work_handler(struct work_struct *work)
        DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
 #endif\r
 \r
-       \r
-\r
-#endif\r
-\r
 }\r
 \r
 static void spi_testgpio_timer(unsigned long data)\r
@@ -618,7 +565,6 @@ static void spi_testgpio_timer(unsigned long data)
        struct spi_fpga_port *port = (struct spi_fpga_port *)data;\r
        port->gpio.gpio_timer.expires  = jiffies + msecs_to_jiffies(1000);\r
        add_timer(&port->gpio.gpio_timer);\r
-       //schedule_work(&port->gpio.spi_gpio_work);\r
        queue_work(port->gpio.spi_gpio_workqueue, &port->gpio.spi_gpio_work);\r
 }\r
 \r
@@ -658,74 +604,6 @@ int spi_gpio_init_first(void)
                \r
 #elif (FPGA_TYPE == ICE_CC196)\r
 \r
-#if 0\r
-       DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
-       spi_out(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO0_TYPE), 0x0000, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO0_TYPE), SEL_GPIO) & 0xffff;\r
-       if(ret != 0x0000)\r
-       DBG("%s:Line=%d,set=0x0000,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-       \r
-       spi_out(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO_DATA), 0x0000, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO_DATA), SEL_GPIO) & 0xffff;\r
-       if(ret != 0x0000)\r
-       DBG("%s:Line=%d,set=0x0000,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-       \r
-       spi_out(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO_DIR), 0xffff, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO_DIR), SEL_GPIO) & 0xffff;\r
-       if(ret != 0xffff)\r
-       DBG("%s:Line=%d,set=0x0000,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-\r
-       spi_out(port, (ICE_SEL_GPIO1 | ICE_SEL_GPIO_DATA), 0x0224, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO1 | ICE_SEL_GPIO_DATA), SEL_GPIO) & 0xffff;\r
-       if(ret != 0x0224)\r
-       DBG("%s:Line=%d,set=0x0000,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-       \r
-       spi_out(port, (ICE_SEL_GPIO1 | ICE_SEL_GPIO_DIR), 0xf7ef, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO1 | ICE_SEL_GPIO_DIR), SEL_GPIO) & 0xffff;\r
-       if(ret != 0xf7ef)\r
-       DBG("%s:Line=%d,set=0x0000,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-       \r
-       spi_out(port, (ICE_SEL_GPIO2 | ICE_SEL_GPIO_DATA), 0x2008, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO2 | ICE_SEL_GPIO_DATA), SEL_GPIO) & 0xffff;\r
-       if(ret != 0x2008)\r
-       DBG("%s:Line=%d,set=0x2008,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-       \r
-       spi_out(port, (ICE_SEL_GPIO2 | ICE_SEL_GPIO_DIR), 0xf378, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO1 | ICE_SEL_GPIO_DIR), SEL_GPIO) & 0xffff;\r
-       if(ret != 0xf378)\r
-       DBG("%s:Line=%d,set=0xf378,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-\r
-       spi_out(port, (ICE_SEL_GPIO3 | ICE_SEL_GPIO_DATA), 0x0000, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO3 | ICE_SEL_GPIO_DATA), SEL_GPIO) & 0xffff;\r
-       if(ret != 0x0000)\r
-       DBG("%s:Line=%d,set=0x0000,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-       \r
-       spi_out(port, (ICE_SEL_GPIO3 | ICE_SEL_GPIO_DIR), 0xffff, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO3 | ICE_SEL_GPIO_DIR), SEL_GPIO) & 0xffff;\r
-       if(ret != 0xffff)\r
-       DBG("%s:Line=%d,set=0xffff,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-\r
-       spi_out(port, (ICE_SEL_GPIO4 | ICE_SEL_GPIO_DATA), 0x0000, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO4 | ICE_SEL_GPIO_DATA), SEL_GPIO) & 0xffff;\r
-       if(ret != 0x0000)\r
-       DBG("%s:Line=%d,set=0x0000,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-       \r
-       spi_out(port, (ICE_SEL_GPIO4 | ICE_SEL_GPIO_DIR), 0xffbf, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO4 | ICE_SEL_GPIO_DIR), SEL_GPIO) & 0xffff;\r
-       if(ret != 0xffbf)\r
-       DBG("%s:Line=%d,set=0xffbf,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-       \r
-       spi_out(port, (ICE_SEL_GPIO5 | ICE_SEL_GPIO_DATA), 0x0000, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO5 | ICE_SEL_GPIO_DATA), SEL_GPIO) & 0xffff;\r
-       if(ret != 0x0000)\r
-       DBG("%s:Line=%d,set=0x0000,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-       \r
-       spi_out(port, (ICE_SEL_GPIO5 | ICE_SEL_GPIO_DIR), 0xffff, SEL_GPIO);\r
-       ret = spi_in(port, (ICE_SEL_GPIO5 | ICE_SEL_GPIO_DIR), SEL_GPIO) & 0xffff;\r
-       if(ret != 0xffff)\r
-       DBG("%s:Line=%d,set=0xffff,ret=0x%x\n",__FUNCTION__,__LINE__,ret);\r
-\r
-#else\r
        spi_gpio_set_pinlevel(SPI_GPIO_P1_00, SPI_GPIO_HIGH);           //LCD_ON output//\r
        spi_gpio_set_pindirection(SPI_GPIO_P1_00, SPI_GPIO_OUT);\r
        spi_gpio_set_pinlevel(SPI_GPIO_P1_01, SPI_GPIO_HIGH);           //LCD_PWR_CTRL output\r
@@ -766,9 +644,9 @@ int spi_gpio_init_first(void)
        spi_gpio_set_pinlevel(SPI_GPIO_P2_03, SPI_GPIO_HIGH);           //AP_PW_EN_TD output\r
        spi_gpio_set_pindirection(SPI_GPIO_P2_03, SPI_GPIO_OUT);\r
        \r
-       spi_gpio_set_pinlevel(SPI_GPIO_P2_04, SPI_GPIO_LOW);            //AP_RESET_TD output\r
+       spi_gpio_set_pinlevel(SPI_GPIO_P2_04, SPI_GPIO_HIGH);           //AP_RESET_TD output\r
        spi_gpio_set_pindirection(SPI_GPIO_P2_04, SPI_GPIO_OUT);\r
-       spi_gpio_set_pinlevel(SPI_GPIO_P2_05, SPI_GPIO_LOW);            //AP_SHUTDOWN_TD_PMU output\r
+       spi_gpio_set_pinlevel(SPI_GPIO_P2_05, SPI_GPIO_HIGH);           //AP_SHUTDOWN_TD_PMU output\r
        spi_gpio_set_pindirection(SPI_GPIO_P2_05, SPI_GPIO_OUT);\r
        spi_gpio_set_pinlevel(SPI_GPIO_P2_06, SPI_GPIO_LOW);            //AP_RESET_CMMB output\r
        spi_gpio_set_pindirection(SPI_GPIO_P2_06, SPI_GPIO_OUT);\r
@@ -796,57 +674,14 @@ int spi_gpio_init_first(void)
        spi_gpio_set_pinlevel(SPI_GPIO_P4_08, SPI_GPIO_LOW);            //CM3605_PS_SHUTDOWN\r
        spi_gpio_set_pindirection(SPI_GPIO_P4_08, SPI_GPIO_OUT);\r
        \r
-#endif\r
-#if SPI_GPIO_TEST\r
-#if (USE_SYS_INT == 0)\r
-       for(i=0;i<81;i++)\r
-       {\r
-               if(i<4)\r
-               {\r
-                       switch(i)\r
-                       {\r
-                               case 0:\r
-                               spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_0, SPI_GPIO_EDGE_FALLING, port);\r
-                               break;\r
-                               case 1:\r
-                               spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_1, SPI_GPIO_EDGE_FALLING, port);\r
-                               break;\r
-                               case 2:\r
-                               spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_2, SPI_GPIO_EDGE_FALLING, port);\r
-                               break;\r
-                               case 3:\r
-                               spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_3, SPI_GPIO_EDGE_FALLING, port);\r
-                               break;\r
-                               \r
-                               default:\r
-                               break;\r
-                       }\r
-                       \r
-               }\r
-               else\r
-               {\r
-                       //if(i<16)\r
-                       //spi_gpio_int_sel(i,SPI_GPIO0_IS_GPIO);\r
-                       spi_gpio_set_pindirection(i, SPI_GPIO_OUT);     \r
-                       ret = spi_gpio_get_pindirection(i);\r
-                       if(ret != SPI_GPIO_OUT)\r
-                       {\r
-                               #if SPI_FPGA_TEST_DEBUG\r
-                               spi_test_wrong_handle();\r
-                               #endif\r
-                               printk("err:PinNum=%d,set_pindirection=%d but get_pindirection=%d\n",i,SPI_GPIO_OUT,ret);       \r
-                       }\r
-               }\r
-\r
-       }\r
-#endif\r
-#endif\r
 #endif\r
 \r
        return 0;\r
 \r
 }\r
 \r
+void spi_gpio_irq_work_handler(struct work_struct *work);\r
+\r
 int spi_gpio_register(struct spi_fpga_port *port)\r
 {\r
 #if SPI_GPIO_TEST\r
@@ -867,6 +702,15 @@ int spi_gpio_register(struct spi_fpga_port *port)
        spin_lock_init(&gpio_lock);\r
        spin_lock_init(&gpio_state_lock);\r
        spin_lock_init(&gpio_irq_lock);\r
+\r
+       port->gpio.spi_gpio_irq_workqueue = create_freezeable_workqueue("spi_gpio_irq_workqueue");\r
+       if (!port->gpio.spi_gpio_irq_workqueue) {\r
+               printk("cannot create spi_gpio_irq workqueue\n");\r
+               return -EBUSY;\r
+       }\r
+       INIT_WORK(&port->gpio.spi_gpio_irq_work, spi_gpio_irq_work_handler);\r
+       INIT_LIST_HEAD(&port->gpio.msg_queue);\r
+\r
        DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);\r
        return 0;\r
 }\r
@@ -975,10 +819,24 @@ static struct fpga_gpio_chip spi_gpio_chip[] = {
 };\r
 \r
 \r
-static void spi_gpio_irq_enable(unsigned irq)\r
+#define ID_SPI_GPIO_IRQ_ENABLE         1\r
+#define ID_SPI_GPIO_IRQ_DISABLE                2\r
+#define ID_SPI_GPIO_IRQ_SET_TYPE       3\r
+#define ID_SPI_GPIO_IRQ_SET_WAKE       4\r
+\r
+struct spi_gpio_irq_transfer\r
+{\r
+       unsigned int irq;\r
+       unsigned int type;\r
+       unsigned int state;\r
+       unsigned int id;\r
+       struct list_head        queue;\r
+};\r
+\r
+static void _spi_gpio_irq_enable(unsigned irq)\r
 {\r
        int gpio = irq_to_gpio(irq) - GPIOS_EXPANDER_BASE;\r
-       printk("%s:line=%d,irq=%d,gpio=%d\n",__FUNCTION__,__LINE__,irq,gpio);\r
+       DBG("%s:line=%d,irq=%d,gpio=%d\n",__FUNCTION__,__LINE__,irq,gpio);\r
        if(gpio < 16)\r
        spi_gpio_int_sel(gpio,SPI_GPIO0_IS_INT);\r
        else\r
@@ -989,10 +847,10 @@ static void spi_gpio_irq_enable(unsigned irq)
        spi_gpio_enable_int(gpio);      \r
 }\r
 \r
-static void spi_gpio_irq_disable(unsigned irq)\r
+static void _spi_gpio_irq_disable(unsigned irq)\r
 {\r
        int gpio = irq_to_gpio(irq) - GPIOS_EXPANDER_BASE;\r
-       printk("%s:line=%d,irq=%d,gpio=%d\n",__FUNCTION__,__LINE__,irq,gpio);\r
+       DBG("%s:line=%d,irq=%d,gpio=%d\n",__FUNCTION__,__LINE__,irq,gpio);\r
        if(gpio < 16)\r
        spi_gpio_int_sel(gpio,SPI_GPIO0_IS_INT);\r
        else\r
@@ -1004,22 +862,11 @@ static void spi_gpio_irq_disable(unsigned irq)
 \r
 }\r
 \r
-\r
-static void spi_gpio_irq_mask(unsigned int irq)\r
-{\r
-       //FPGA do not support irq mask\r
-}\r
-\r
-static void spi_gpio_irq_unmask(unsigned int irq)\r
-{\r
-       //FPGA do not support irq unmask\r
-}\r
-\r
-static int spi_gpio_irq_set_type(unsigned int irq, unsigned int type)\r
+static int _spi_gpio_irq_set_type(unsigned int irq, unsigned int type)\r
 {\r
        int gpio = irq_to_gpio(irq) - GPIOS_EXPANDER_BASE;\r
        int int_type = 0;\r
-       printk("%s:line=%d,irq=%d,type=%d,gpio=%d\n",__FUNCTION__,__LINE__,irq,type,gpio);\r
+       DBG("%s:line=%d,irq=%d,type=%d,gpio=%d\n",__FUNCTION__,__LINE__,irq,type,gpio);\r
        if(gpio < 16)\r
        spi_gpio_int_sel(gpio,SPI_GPIO0_IS_INT);\r
        else\r
@@ -1043,13 +890,156 @@ static int spi_gpio_irq_set_type(unsigned int irq, unsigned int type)
        return 0;\r
 }\r
 \r
-static int spi_gpio_irq_set_wake(unsigned irq, unsigned state)\r
+static int _spi_gpio_irq_set_wake(unsigned irq, unsigned state)\r
 {\r
        //unsigned int pin = irq_to_gpio(irq);\r
        set_irq_wake(irq, state);\r
        return 0;\r
 }\r
 \r
+void spi_gpio_irq_work_handler(struct work_struct *work)\r
+{\r
+       unsigned int irq;\r
+       unsigned int type;\r
+       unsigned int state;\r
+       unsigned int id;\r
+       struct spi_fpga_port *port =\r
+               container_of(work, struct spi_fpga_port, gpio.spi_gpio_irq_work);\r
+\r
+       while (!list_empty(&port->gpio.msg_queue)) \r
+       {\r
+               struct spi_gpio_irq_transfer    *t = NULL;\r
+               list_for_each_entry(t, &port->gpio.msg_queue, queue)\r
+               {\r
+                       irq = t->irq;\r
+                       type = t->type;\r
+                       state = t->state;\r
+                       id = t->id;\r
+                       if ((irq == 0) || (id == 0)) \r
+                               break;  \r
+                       printk("%s:irq=%d,type=%d,state=%d,id=%d\n",__FUNCTION__,irq,type,state,id);\r
+                       switch(id)\r
+                       {\r
+                               case ID_SPI_GPIO_IRQ_ENABLE:\r
+                                       _spi_gpio_irq_enable(irq);\r
+                                       break;\r
+                               case ID_SPI_GPIO_IRQ_DISABLE:\r
+                                       _spi_gpio_irq_disable(irq);\r
+                                       break;\r
+                               case ID_SPI_GPIO_IRQ_SET_TYPE:\r
+                                       _spi_gpio_irq_set_type(irq,type);\r
+                                       break;\r
+                               case ID_SPI_GPIO_IRQ_SET_WAKE:\r
+                                       _spi_gpio_irq_set_wake(irq,state);\r
+                                       break;\r
+                               default:\r
+                                       break;\r
+                                       \r
+                       }\r
+                       kfree(t);\r
+               }\r
+               list_del_init(&port->gpio.msg_queue);\r
+       }\r
+}\r
+\r
+\r
+static void spi_gpio_irq_enable(unsigned irq)\r
+{\r
+       struct spi_fpga_port *port = pFpgaPort;\r
+       struct spi_gpio_irq_transfer *t;\r
+       unsigned long flags;\r
+       t = kzalloc(sizeof(struct spi_gpio_irq_transfer), GFP_KERNEL);\r
+       if (!t)\r
+       {\r
+               printk("err:%s:ENOMEM\n",__FUNCTION__);\r
+               return ;\r
+       }\r
+       t->irq = irq;\r
+       t->id = ID_SPI_GPIO_IRQ_ENABLE;\r
+       \r
+       spin_lock_irqsave(&port->spi_lock, flags);\r
+       list_add_tail(&t->queue, &port->gpio.msg_queue);\r
+       queue_work(port->gpio.spi_gpio_irq_workqueue, &port->gpio.spi_gpio_irq_work);\r
+       spin_unlock_irqrestore(&port->spi_lock, flags);\r
+}\r
+\r
+static void spi_gpio_irq_disable(unsigned irq)\r
+{\r
+       struct spi_fpga_port *port = pFpgaPort;\r
+       struct spi_gpio_irq_transfer *t;\r
+       unsigned long flags;\r
+       t = kzalloc(sizeof(struct spi_gpio_irq_transfer), GFP_KERNEL);\r
+       if (!t)\r
+       {\r
+               printk("err:%s:ENOMEM\n",__FUNCTION__);\r
+               return ;\r
+       }\r
+       t->irq = irq;\r
+       t->id = ID_SPI_GPIO_IRQ_DISABLE;\r
+       \r
+       spin_lock_irqsave(&port->spi_lock, flags);\r
+       list_add_tail(&t->queue, &port->gpio.msg_queue);\r
+       queue_work(port->gpio.spi_gpio_irq_workqueue, &port->gpio.spi_gpio_irq_work);\r
+       spin_unlock_irqrestore(&port->spi_lock, flags);\r
+\r
+\r
+}\r
+\r
+static void spi_gpio_irq_mask(unsigned int irq)\r
+{\r
+       //FPGA do not support irq mask\r
+}\r
+\r
+static void spi_gpio_irq_unmask(unsigned int irq)\r
+{\r
+       //FPGA do not support irq unmask\r
+}\r
+\r
+static int spi_gpio_irq_set_type(unsigned int irq, unsigned int type)\r
+{\r
+       struct spi_fpga_port *port = pFpgaPort;\r
+       struct spi_gpio_irq_transfer *t;\r
+       unsigned long flags;\r
+       t = kzalloc(sizeof(struct spi_gpio_irq_transfer), GFP_KERNEL);\r
+       if (!t)\r
+       {\r
+               printk("err:%s:ENOMEM\n",__FUNCTION__);\r
+               return -ENOMEM;\r
+       }\r
+       t->irq = irq;\r
+       t->id = ID_SPI_GPIO_IRQ_SET_TYPE;\r
+       t->type = type;\r
+       \r
+       spin_lock_irqsave(&port->spi_lock, flags);\r
+       list_add_tail(&t->queue, &port->gpio.msg_queue);\r
+       queue_work(port->gpio.spi_gpio_irq_workqueue, &port->gpio.spi_gpio_irq_work);\r
+       spin_unlock_irqrestore(&port->spi_lock, flags);\r
+       return 0;\r
+}\r
+\r
+static int spi_gpio_irq_set_wake(unsigned irq, unsigned state)\r
+{\r
+       struct spi_fpga_port *port = pFpgaPort;\r
+       struct spi_gpio_irq_transfer *t;\r
+       unsigned long flags;\r
+       t = kzalloc(sizeof(struct spi_gpio_irq_transfer), GFP_KERNEL);\r
+       if (!t)\r
+       {\r
+               printk("err:%s:ENOMEM\n",__FUNCTION__);\r
+               return -ENOMEM;\r
+       }\r
+       t->irq = irq;\r
+       t->id = ID_SPI_GPIO_IRQ_SET_WAKE;\r
+       t->state = state;\r
+       \r
+       spin_lock_irqsave(&port->spi_lock, flags);\r
+       list_add_tail(&t->queue, &port->gpio.msg_queue);\r
+       queue_work(port->gpio.spi_gpio_irq_workqueue, &port->gpio.spi_gpio_irq_work);\r
+       spin_unlock_irqrestore(&port->spi_lock, flags);\r
+       return 0;\r
+}\r
+\r
+\r
 static struct irq_chip spi_gpio_irq_chip = {\r
        .name           = "SPI_GPIO_IRQ",\r
        .enable                 = spi_gpio_irq_enable,\r
@@ -1074,7 +1064,7 @@ void spi_gpio_test_gpio_irq_init(void)
                        printk("%s:failed to request GPIO[%d]\n",__FUNCTION__,gpio);\r
                }\r
        }\r
-#if USE_SYS_INT\r
+\r
        for(i=0;i<4;i++)\r
        {\r
                gpio = GPIOS_EXPANDER_BASE+i;\r
@@ -1109,7 +1099,7 @@ void spi_gpio_test_gpio_irq_init(void)
                        }       \r
                        break;\r
 \r
-                       case 9:\r
+                       case 3:\r
                        ret = request_irq(irq ,spi_gpio_int_test_3,IRQF_TRIGGER_FALLING,NULL,port);\r
                        if(ret)\r
                        {\r
@@ -1123,7 +1113,6 @@ void spi_gpio_test_gpio_irq_init(void)
                }\r
        \r
        }\r
-#endif\r
 \r
 #endif\r
 \r
@@ -1155,13 +1144,10 @@ void spi_gpio_irq_setup(void)
                set_irq_flags(pin+j, IRQF_VALID);\r
        }\r
 \r
-       //set_irq_chip_data(pin+j, this);\r
-       //set_irq_chained_handler(pin+j, spi_fpga_irq);\r
+       printk("%s: %d gpio irqs in %d banks\n", __FUNCTION__, pin+j-GPIOS_EXPANDER_BASE, spi_gpio_banks);\r
 \r
-       printk("%s: %d gpio irqs in %d banks\n", __FUNCTION__, pin-GPIOS_EXPANDER_BASE, spi_gpio_banks);\r
-#if SPI_GPIO_TEST\r
        spi_gpio_test_gpio_irq_init();\r
-#endif\r
+\r
 }\r
 \r
 \r