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