danube ssc interrupt cleanup

SVN-Revision: 9764
This commit is contained in:
John Crispin 2007-12-15 15:32:20 +00:00
parent 66fea87684
commit b48258f673

View file

@ -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: