diff options
author | John Crispin <blogic@openwrt.org> | 2007-12-15 15:32:20 +0000 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2007-12-15 15:32:20 +0000 |
commit | 5d866bc0f94db223fc0a6c0a44f4ab26a8b02d59 (patch) | |
tree | dbc8eebe22347f008f0b55745204dac764e69242 /target/linux | |
parent | f248d86feeb89390fe6facafbef3048def3888fe (diff) | |
download | master-187ad058-5d866bc0f94db223fc0a6c0a44f4ab26a8b02d59.tar.gz master-187ad058-5d866bc0f94db223fc0a6c0a44f4ab26a8b02d59.tar.bz2 master-187ad058-5d866bc0f94db223fc0a6c0a44f4ab26a8b02d59.zip |
danube ssc interrupt cleanup
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@9764 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/danube/files/drivers/char/danube_ssc.c | 117 |
1 files changed, 12 insertions, 105 deletions
diff --git a/target/linux/danube/files/drivers/char/danube_ssc.c b/target/linux/danube/files/drivers/char/danube_ssc.c index cd0b4d387a..ecaa594866 100644 --- a/target/linux/danube/files/drivers/char/danube_ssc.c +++ b/target/linux/danube/files/drivers/char/danube_ssc.c @@ -90,9 +90,6 @@ int ifx_ssc_close (struct inode *, struct file *); /* other forward declarations */ static unsigned int ifx_ssc_get_kernel_clk (struct ifx_ssc_port *info); -static void ifx_ssc_rx_int (int, void *, struct pt_regs *); -static void ifx_ssc_tx_int (int, void *, struct pt_regs *); -static void ifx_ssc_err_int (int, void *, struct pt_regs *); #ifdef SSC_FRAME_INT_ENABLE static void ifx_ssc_frm_int (int, void *, struct pt_regs *); #endif @@ -384,24 +381,26 @@ tx_int (struct ifx_ssc_port *info) } // tx_int -static void -ifx_ssc_rx_int (int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t +ifx_ssc_rx_int (int irq, void *dev_id) { struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id; - //WRITE_PERIPHERAL_REGISTER(IFX_SSC_R_BIT, info->mapbase + IFX_SSC_IRN_CR); rx_int (info); + + return IRQ_HANDLED; } -static void -ifx_ssc_tx_int (int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t +ifx_ssc_tx_int (int irq, void *dev_id) { struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id; - //WRITE_PERIPHERAL_REGISTER(IFX_SSC_T_BIT, info->mapbase + IFX_SSC_IRN_CR); tx_int (info); + + return IRQ_HANDLED; } -static void -ifx_ssc_err_int (int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t +ifx_ssc_err_int (int irq, void *dev_id) { struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id; unsigned int state; @@ -441,6 +440,8 @@ ifx_ssc_err_int (int irq, void *dev_id, struct pt_regs *regs) info->mapbase + IFX_SSC_WHBSTATE); local_irq_restore (flags); + + return IRQ_HANDLED; } #ifdef SSC_FRAME_INT_ENABLE @@ -746,100 +747,6 @@ ifx_ssc_read_helper (struct ifx_ssc_port *info, char *buf, size_t len, return (ret_val); } // ifx_ssc_read_helper -#if 0 -/* helper routine to handle reads from the kernel or user-space */ -/* appropriate in interrupt context */ -static ssize_t -ifx_ssc_read_helper (struct ifx_ssc_port *info, char *buf, size_t len, - int from_kernel) -{ - ssize_t ret_val; - unsigned long flags; - DECLARE_WAITQUEUE (wait, current); - - if (info->opts.modeRxTx == IFX_SSC_MODE_TX) - return -EFAULT; - local_irq_save (flags); - info->rxbuf_ptr = info->rxbuf; - info->rxbuf_end = info->rxbuf + len; - if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { - if ((info->txbuf == NULL) || - (info->txbuf != info->txbuf_ptr) || - (info->txbuf_end != len + info->txbuf)) { - local_irq_restore (flags); - printk ("IFX SSC - %s: write must be called before calling " "read in combined RX/TX!\n", __FUNCTION__); - return -EFAULT; - } - local_irq_restore (flags); - /* should enable tx, right? */ - tx_int (info); - if (!in_irq ()) { - if (info->txbuf_ptr < info->txbuf_end) { - ifx_int_wrapper.enable (info->txirq); - } - ifx_int_wrapper.enable (info->rxirq); - } - } - else { // rx mode - local_irq_restore (flags); - if (READ_PERIPHERAL_REGISTER (info->mapbase + IFX_SSC_RXCNT) & - IFX_SSC_RXCNT_TODO_MASK) - return -EBUSY; - if (!in_irq ()) { - ifx_int_wrapper.enable (info->rxirq); - } - - if (len < IFX_SSC_RXREQ_BLOCK_SIZE) - WRITE_PERIPHERAL_REGISTER (len << - IFX_SSC_RXREQ_RXCOUNT_OFFSET, - info->mapbase + - IFX_SSC_RXREQ); - else - WRITE_PERIPHERAL_REGISTER (IFX_SSC_RXREQ_BLOCK_SIZE << - IFX_SSC_RXREQ_RXCOUNT_OFFSET, - info->mapbase + - IFX_SSC_RXREQ); - } - if (in_irq ()) { - do { - rx_int (info); - if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { - tx_int (info); - } - - if (info->rxbuf_ptr >= info->rxbuf_end) - break; - } while (1); - ret_val = info->rxbuf_ptr - info->rxbuf; - } - else { - __add_wait_queue (&info->rwait, &wait); - set_current_state (TASK_INTERRUPTIBLE); - // wakeup done in rx_int - - do { - local_irq_save (flags); - if (info->rxbuf_ptr >= info->rxbuf_end) - break; - local_irq_restore (flags); - - if (signal_pending (current)) { - ret_val = -ERESTARTSYS; - goto out; - } - schedule (); - } while (1); - - ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len - local_irq_restore (flags); - - out: - current->state = TASK_RUNNING; - __remove_wait_queue (&info->rwait, &wait); - } - return (ret_val); -} // ifx_ssc_read_helper -#endif /* helper routine to handle writes to the kernel or user-space */ /* info->txbuf has two cases: |