add suspend and resume support for fpga
authorluowei <lw@rock-chips.com>
Thu, 9 Sep 2010 12:06:52 +0000 (20:06 +0800)
committerluowei <lw@rock-chips.com>
Thu, 9 Sep 2010 12:06:52 +0000 (20:06 +0800)
drivers/fpga/spi_fpga_init.c
drivers/fpga/spi_uart.c

index 0a2ddea26ddcbe63c8fe6c71d8c4761e9097af88..0ec51b5877258f05e7b65bb90d820709b83feb6e 100755 (executable)
@@ -72,7 +72,7 @@ static void spi_fpga_trans_work_handler(struct work_struct *work)
        struct spi_fpga_port *port =\r
                container_of(work, struct spi_fpga_port, fpga_trans_work);\r
        unsigned long flags;\r
-       spin_lock_irqsave(&port->work_lock, flags);\r
+       \r
        while (!list_empty(&port->trans_queue)) \r
        {\r
                struct spi_fpga_transfer        *t = NULL, *tmp;\r
@@ -94,9 +94,11 @@ static void spi_fpga_trans_work_handler(struct work_struct *work)
                        kfree(t->txbuf);\r
                        kfree(t);\r
                }\r
+               spin_lock_irqsave(&port->work_lock, flags);\r
                list_del_init(&port->trans_queue);\r
+               spin_unlock_irqrestore(&port->work_lock, flags);\r
        }\r
-       spin_unlock_irqrestore(&port->work_lock, flags);\r
+\r
 \r
 }\r
 \r
@@ -110,7 +112,7 @@ int spi_write_work(struct spi_device *spi, const u8 *buf, size_t len)
        if (!t)\r
        {\r
                printk("err:%s:ENOMEM\n",__FUNCTION__);\r
-               return ;\r
+               return -ENOMEM;\r
        }\r
 \r
        t->txbuf = (char *)kmalloc(32, GFP_KERNEL);\r
@@ -297,7 +299,7 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)
                        rx_buf[0] = 0;\r
                        rx_buf[1] = 0;  \r
                        stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx);\r
-                       result = rx_buf[1];\r
+                       result = (rx_buf[0] << 8) | rx_buf[1];\r
                        DBG("%s,SEL_INT reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff);\r
                        break;\r
                default:\r
@@ -405,7 +407,7 @@ static void spi_fpga_irq_work_handler(struct work_struct *work)
 \r
        DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);\r
        \r
-       ret = spi_in(port, ICE_SEL_READ_INT_TYPE, READ_TOP_INT);\r
+       ret = spi_in(port, ICE_SEL_READ_INT_TYPE, READ_TOP_INT) & 0xff;\r
        if((ret | ICE_INT_TYPE_UART0) == ICE_INT_TYPE_UART0)\r
        {\r
 #if defined(CONFIG_SPI_FPGA_UART)\r
@@ -472,12 +474,6 @@ static irqreturn_t spi_fpga_irq(int irq, void *dev_id)
 \r
 static int spi_set_sysclk(int set)\r
 {\r
-       int ret;\r
-       ret = gpio_request(SPI_FPGA_STANDBY_PIN, NULL);\r
-       if (ret) {\r
-               printk("%s:failed to request standby pin\n",__FUNCTION__);\r
-               return ret;\r
-       }\r
        rk2818_mux_api_set(GPIOH7_HSADCCLK_SEL_NAME,IOMUXB_GPIO1_D7);   \r
        gpio_direction_output(SPI_FPGA_STANDBY_PIN,set);\r
 \r
@@ -527,7 +523,11 @@ static int __devinit spi_fpga_probe(struct spi_device * spi)
        \r
        mutex_init(&port->spi_lock);\r
        spin_lock_init(&port->work_lock);\r
-       \r
+       ret = gpio_request(SPI_FPGA_STANDBY_PIN, NULL);\r
+       if (ret) {\r
+               printk("%s:failed to request standby pin\n",__FUNCTION__);\r
+               return ret;\r
+       }\r
        spi_set_sysclk(GPIO_HIGH);\r
 \r
 #if SPI_FPGA_TRANS_WORK\r
@@ -648,17 +648,46 @@ static int __devexit spi_fpga_remove(struct spi_device *spi)
 \r
 #ifdef CONFIG_PM\r
 \r
-static int spi_fpga_suspend(struct spi_device *spi, pm_message_t state)\r
+static int spi_fpga_wait_suspend(struct spi_fpga_port *port)\r
 {\r
-       //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
+       int i,n_tx,n_rx;\r
+       for(i=0;i<1000;i++)\r
+       {\r
+               n_tx = spi_in(port, UART_LSR, READ_TOP_INT);\r
+               n_rx = spi_in(port, UART_LSR, SEL_UART);\r
+               if((((n_tx >> 8) & 0x3f) == 0) && (((n_rx >> 8) & 0x3f) == 0))  //no data in tx_buf and rx_buf\r
+               {\r
+                       printk("%s,i=%d\n",__FUNCTION__,i);\r
+                       return 0;       \r
+               }\r
+       }\r
+       \r
+       return -1;\r
+}\r
 \r
+static int spi_fpga_suspend(struct spi_device *spi, pm_message_t state)\r
+{\r
+       struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
+       int ret;\r
+       ret = spi_fpga_wait_suspend(port);\r
+       if(!ret)\r
+       {\r
+               spi_set_sysclk(GPIO_LOW);\r
+       }\r
+       else\r
+       {\r
+               printk("fail to suspend fpga because it is sending or recieve data!\n");\r
+               return -1;\r
+       }\r
+       printk("%s\n",__FUNCTION__);\r
        return 0;\r
 }\r
 \r
 static int spi_fpga_resume(struct spi_device *spi)\r
 {\r
        //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
-\r
+       spi_set_sysclk(GPIO_HIGH);\r
+       printk("%s\n",__FUNCTION__);\r
        return 0;\r
 }\r
 \r
index 69e24dbd08d3334083aeb597bff71fe79952a269..28eba8290cf5dadc30fa3a30f6ea9aae7ca1fc93 100755 (executable)
@@ -371,7 +371,7 @@ static void spi_uart_start_tx(struct spi_uart *uart)
        if (!(uart->ier & UART_IER_THRI)) {\r
                uart->ier |= UART_IER_THRI;\r
                spi_out(port, UART_IER, uart->ier, SEL_UART);\r
-               printk("t,");\r
+               DBG("t,");\r
        }       \r
        \r
        DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);\r
@@ -402,7 +402,7 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
        struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);\r
        unsigned int ch, flag;\r
        int max_count = 1024;\r
-       //printk("rx:");\r
+       DBG("rx:");\r
 #if SPI_UART_TXRX_BUF\r
        int ret,count,stat = 0;\r
        int i = 0;\r
@@ -433,21 +433,19 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
                        uart->icount.rx++;\r
                        ch = buf[i];\r
                        tty_insert_flip_char(tty, ch, flag);\r
-                       //if(gBaud == 1500000)\r
-                       //printk("0x%x,",ch);\r
+                       DBG("0x%x,",ch);\r
                }\r
-               //printk("\n");\r
+               DBG("\n");\r
        }       \r
 \r
        tty_flip_buffer_push(tty); \r
-       //if(gBaud == 1500000)\r
-       //printk("\n");\r
+       DBG("\n");\r
        \r
 #else  \r
        while (--max_count >0 )\r
        {\r
                ch = spi_in(port, UART_RX, SEL_UART);//\r
-               //printk("0x%x,",ch&0xff);\r
+               DBG("0x%x,",ch&0xff);\r
                flag = TTY_NORMAL;\r
                uart->icount.rx++;\r
                //--max_count;\r
@@ -491,12 +489,12 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
                if(!(*status & UART_LSR_DR))\r
                        break;\r
        } \r
-       //printk("\n");\r
+       DBG("\n");\r
        DBG("%s:LINE=%d,rx_count=%d\n",__FUNCTION__,__LINE__,(1024-max_count));\r
        tty_flip_buffer_push(tty);\r
 \r
 #endif\r
-       printk("r%d\n",1024-max_count);\r
+       DBG("r%d\n",1024-max_count);\r
        \r
 }\r
 \r
@@ -522,7 +520,7 @@ static void spi_uart_transmit_chars(struct spi_uart *uart)
                //printk("circ_empty()\n");\r
                return;\r
        }\r
-       //printk("tx:");\r
+       DBG("tx:");\r
 \r
 #if SPI_UART_TXRX_BUF\r
        //send several bytes one time\r
@@ -532,15 +530,13 @@ static void spi_uart_transmit_chars(struct spi_uart *uart)
                if (circ_empty(xmit))\r
                break;\r
                buf[SPI_UART_FIFO_LEN - count] = xmit->buf[xmit->tail];\r
-               //if(gBaud == 1500000)\r
-               //printk("0x%x,",buf[SPI_UART_FIFO_LEN - count]&0xff);\r
+               DBG("0x%x,",buf[SPI_UART_FIFO_LEN - count]&0xff);\r
                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);\r
                uart->icount.tx++;\r
                --count;\r
 \r
        }\r
-       //if(gBaud == 1500000)\r
-       //printk("\n");\r
+       DBG("\n");\r
        if(SPI_UART_FIFO_LEN - count > 0)\r
        spi_uart_write_buf(uart,buf,SPI_UART_FIFO_LEN - count);\r
 #else\r
@@ -549,7 +545,7 @@ static void spi_uart_transmit_chars(struct spi_uart *uart)
        while(count > 0)\r
        {\r
                spi_out(port, UART_TX, xmit->buf[xmit->tail], SEL_UART);\r
-               //printk("0x%x,",xmit->buf[xmit->tail]);\r
+               DBG("0x%x,",xmit->buf[xmit->tail]);\r
                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);\r
                uart->icount.tx++;\r
                --count;\r
@@ -557,22 +553,22 @@ static void spi_uart_transmit_chars(struct spi_uart *uart)
                break;  \r
        }\r
 #endif\r
-       //printk("\n");\r
+       DBG("\n");\r
        DBG("%s:LINE=%d,tx_count=%d\n",__FUNCTION__,__LINE__,(SPI_UART_FIFO_LEN-count));\r
        if (circ_chars_pending(xmit) < WAKEUP_CHARS)\r
        {       \r
                tty_wakeup(uart->tty);\r
-               //printk("k,");\r
+               DBG("k,");\r
        }\r
        DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
        if (circ_empty(xmit))\r
        {\r
                DBG("circ_empty(xmit)\n");\r
                spi_uart_stop_tx(uart);\r
-               //printk("e,");\r
+               DBG("e,");\r
        }\r
        \r
-       printk("t%d\n",SPI_UART_FIFO_LEN-count);\r
+       DBG("t%d\n",SPI_UART_FIFO_LEN-count);\r
 \r
        DBG("uart->tty->hw_stopped = %d\n",uart->tty->hw_stopped);\r
 }\r
@@ -984,7 +980,7 @@ static int spi_uart_write(struct tty_struct * tty, const unsigned char *buf,
                mutex_lock(&port->spi_lock);\r
                        DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
                        /*Note:ICE65L08 output a 'Transmitter holding register interrupt' after 1us*/\r
-                       printk("s,");\r
+                       DBG("s,");\r
                        spi_uart_start_tx(uart);\r
                        //spi_uart_handle_irq(port->spi);\r
                mutex_unlock(&port->spi_lock);  \r