diff options
author | Roshni Shah <roshni.shah@timesys.com> | 2014-01-07 00:34:13 -0500 |
---|---|---|
committer | Anthony Felice <tony.felice@timesys.com> | 2014-02-25 16:23:34 -0500 |
commit | 7a27fd26d2b5b732e12ecea13a846679cbafe9a9 (patch) | |
tree | 3a27ce9462289e77b2e2f4ab63a00db86ed576e7 | |
parent | 05acac3e2a0984e0278cf75387bbeb6a1c772eb8 (diff) |
Fixed a panic seen as soon as you type a character on the terminal when EDMA is disabled in UART config. The receive interrupt was attempting to schedule a work queue only defined if EDMA is enabled.3.0-pcm052-ts2.9
kernel BUG at kernel/workqueue.c:1037!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
-rw-r--r-- | drivers/tty/serial/mvf.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/drivers/tty/serial/mvf.c b/drivers/tty/serial/mvf.c index 814a7daa56f0..1b730afd4312 100644 --- a/drivers/tty/serial/mvf.c +++ b/drivers/tty/serial/mvf.c @@ -84,22 +84,22 @@ struct imx_port { unsigned int format_9bits:1; /* 9bits data format */ unsigned short trcv_delay; /* transceiver delay */ unsigned char ma_addr; /* Match address */ - struct clk *clk; + struct clk *clk; unsigned int tx_fifo_size, rx_fifo_size; /* DMA fields */ - int enable_dma; + int enable_dma; unsigned long dma_tx_ch; /* configured eDMA channel */ struct imx_dma_data dma_data; struct dma_chan *dma_chan_rx, *dma_chan_tx; struct scatterlist rx_sgl, tx_sgl; - void *rx_buf; + void *rx_buf; unsigned char *tx_buf; unsigned int rx_bytes, tx_bytes; struct work_struct tsk_rx, tsk_dma_tx; unsigned int dma_tx_nents; - bool dma_is_rxing, dma_is_txing; + bool dma_is_rxing, dma_is_txing; wait_queue_head_t dma_wait; }; @@ -226,21 +226,21 @@ static void tx_uart_dmarun(struct imx_port *sport) if (sport->dma_tx_nents == 0) return; - mcf_edma_set_tcd_params(sport->dma_tx_ch, - (u32)sg_phys(&sport->tx_sgl), - (u32)(sport->port.mapbase + MXC_UARTDR), + mcf_edma_set_tcd_params(sport->dma_tx_ch, /* channel number */ + (u32)sg_phys(&sport->tx_sgl), /* source */ + (u32)(sport->port.mapbase + MXC_UARTDR), /* dest */ MCF_EDMA_TCD_ATTR_SSIZE_8BIT | - MCF_EDMA_TCD_ATTR_DSIZE_8BIT, - 1, - 1, - 0, - sport->tx_bytes, - 0, - 0, - 0, + MCF_EDMA_TCD_ATTR_DSIZE_8BIT, /* attr */ + 1, /* soff */ + 1, /* nbytes */ + 0, /* slast */ + sport->tx_bytes, /* citer */ + 0, /* biter */ + 0, /* doff */ + 0, /* dlast_sga */ 1, /* major_int */ 1, /* disable_req */ - 0 + 0 /* enabled sg */ ); sport->dma_is_txing = 1; mcf_edma_enable_transfer(sport->dma_tx_ch); @@ -304,7 +304,7 @@ static void dma_tx_work(struct work_struct *w) { if (sport->port.state->port.tty) { - uart_write_wakeup(&sport->port); + uart_write_wakeup(&sport->port); } } @@ -359,7 +359,7 @@ static irqreturn_t imx_txint(int irq, void *dev_id) { if (sport->port.state->port.tty) { - uart_write_wakeup(&sport->port); + uart_write_wakeup(&sport->port); } } @@ -446,8 +446,10 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) out: spin_unlock_irqrestore(&sport->port.lock, flags); - //TODO: Check tsk_rx, seems to be edma related. - schedule_work(&sport->tsk_rx); + if (sport->rx_bytes) { + tty_flip_buffer_push(tty); + sport->rx_bytes = 0; + } return IRQ_HANDLED; } |