wctc4xxp: Use hardware timer for polling and not kernel timer
Simplifies the logic when polling is enabled. No need to worry about any system factors when scheduling the default kernel timer. Signed-off-by: Shaun Ruffell <sruffell@digium.com> Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
This commit is contained in:
parent
0efce00a09
commit
354d88cd41
@ -78,7 +78,7 @@
|
|||||||
|
|
||||||
/* The total number of active channels over which the driver will start polling
|
/* The total number of active channels over which the driver will start polling
|
||||||
* the card every 10 ms. */
|
* the card every 10 ms. */
|
||||||
#define POLLING_CALL_THRESHOLD 40
|
#define POLLING_CALL_THRESHOLD 8
|
||||||
|
|
||||||
#define INVALID 999 /* Used to mark invalid channels, commands, etc.. */
|
#define INVALID 999 /* Used to mark invalid channels, commands, etc.. */
|
||||||
#define MAX_CHANNEL_PACKETS 5
|
#define MAX_CHANNEL_PACKETS 5
|
||||||
@ -356,7 +356,6 @@ struct wcdte {
|
|||||||
#endif
|
#endif
|
||||||
struct timer_list watchdog;
|
struct timer_list watchdog;
|
||||||
atomic_t open_channels;
|
atomic_t open_channels;
|
||||||
struct timer_list polling;
|
|
||||||
#if HZ > 100
|
#if HZ > 100
|
||||||
unsigned long jiffies_at_last_poll;
|
unsigned long jiffies_at_last_poll;
|
||||||
#endif
|
#endif
|
||||||
@ -1792,10 +1791,12 @@ wctc4xxp_setintmask(struct wcdte *wc, unsigned int intmask)
|
|||||||
wctc4xxp_setctl(wc, 0x0038, intmask);
|
wctc4xxp_setctl(wc, 0x0038, intmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const u32 DEFAULT_INTERRUPTS = 0x0001a0c0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wctc4xxp_enable_interrupts(struct wcdte *wc)
|
wctc4xxp_enable_interrupts(struct wcdte *wc)
|
||||||
{
|
{
|
||||||
wctc4xxp_setintmask(wc, 0x0001a0c0);
|
wctc4xxp_setintmask(wc, DEFAULT_INTERRUPTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1810,8 +1811,9 @@ static void
|
|||||||
wctc4xxp_enable_polling(struct wcdte *wc)
|
wctc4xxp_enable_polling(struct wcdte *wc)
|
||||||
{
|
{
|
||||||
set_bit(DTE_POLLING, &wc->flags);
|
set_bit(DTE_POLLING, &wc->flags);
|
||||||
mod_timer(&wc->polling, jiffies + 1);
|
wctc4xxp_setctl(wc, 0x0058, 0x1000a);
|
||||||
wctc4xxp_disable_interrupts(wc);
|
/* Enable the general purpose timer interrupt. */
|
||||||
|
wctc4xxp_setintmask(wc, (DEFAULT_INTERRUPTS | (1 << 11)) & ~0x41);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1857,6 +1859,7 @@ static void
|
|||||||
wctc4xxp_disable_polling(struct wcdte *wc)
|
wctc4xxp_disable_polling(struct wcdte *wc)
|
||||||
{
|
{
|
||||||
clear_bit(DTE_POLLING, &wc->flags);
|
clear_bit(DTE_POLLING, &wc->flags);
|
||||||
|
wctc4xxp_setctl(wc, 0x0058, 0x0);
|
||||||
wctc4xxp_enable_interrupts(wc);
|
wctc4xxp_enable_interrupts(wc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2014,23 +2017,6 @@ wctc4xxp_handle_receive_ring(struct wcdte *wc)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
__wctc4xxp_polling(struct wcdte *wc)
|
|
||||||
{
|
|
||||||
if (wctc4xxp_handle_receive_ring(wc))
|
|
||||||
schedule_work(&wc->deferred_work);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
wctc4xxp_polling(unsigned long data)
|
|
||||||
{
|
|
||||||
struct wcdte *wc = (struct wcdte *)data;
|
|
||||||
__wctc4xxp_polling(wc);
|
|
||||||
if (test_bit(DTE_POLLING, &wc->flags))
|
|
||||||
mod_timer(&wc->polling, jiffies + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Called with a buffer in which to copy a transcoded frame. */
|
/* Called with a buffer in which to copy a transcoded frame. */
|
||||||
static ssize_t
|
static ssize_t
|
||||||
wctc4xxp_read(struct file *file, char __user *frame, size_t count, loff_t *ppos)
|
wctc4xxp_read(struct file *file, char __user *frame, size_t count, loff_t *ppos)
|
||||||
@ -2187,18 +2173,6 @@ wctc4xxp_write(struct file *file, const char __user *frame,
|
|||||||
atomic_inc(&cpvt->stats.packets_sent);
|
atomic_inc(&cpvt->stats.packets_sent);
|
||||||
wctc4xxp_transmit_cmd(wc, cmd);
|
wctc4xxp_transmit_cmd(wc, cmd);
|
||||||
|
|
||||||
if (test_bit(DTE_POLLING, &wc->flags)) {
|
|
||||||
#if HZ == 100
|
|
||||||
__wctc4xxp_polling(wc);
|
|
||||||
#else
|
|
||||||
if (jiffies != wc->jiffies_at_last_poll) {
|
|
||||||
wc->jiffies_at_last_poll = jiffies;
|
|
||||||
__wctc4xxp_polling(wc);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2581,7 +2555,9 @@ DAHDI_IRQ_HANDLER(wctc4xxp_interrupt)
|
|||||||
u32 reg;
|
u32 reg;
|
||||||
#define TX_COMPLETE_INTERRUPT 0x00000001
|
#define TX_COMPLETE_INTERRUPT 0x00000001
|
||||||
#define RX_COMPLETE_INTERRUPT 0x00000040
|
#define RX_COMPLETE_INTERRUPT 0x00000040
|
||||||
#define NORMAL_INTERRUPTS (TX_COMPLETE_INTERRUPT | RX_COMPLETE_INTERRUPT)
|
#define TIMER_INTERRUPT (1<<11)
|
||||||
|
#define NORMAL_INTERRUPTS (TX_COMPLETE_INTERRUPT | RX_COMPLETE_INTERRUPT | \
|
||||||
|
TIMER_INTERRUPT)
|
||||||
|
|
||||||
/* Read and clear interrupts */
|
/* Read and clear interrupts */
|
||||||
ints = __wctc4xxp_getctl(wc, 0x0028);
|
ints = __wctc4xxp_getctl(wc, 0x0028);
|
||||||
@ -2601,6 +2577,11 @@ DAHDI_IRQ_HANDLER(wctc4xxp_interrupt)
|
|||||||
reg |= RX_COMPLETE_INTERRUPT;
|
reg |= RX_COMPLETE_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ints & TIMER_INTERRUPT) {
|
||||||
|
wctc4xxp_handle_receive_ring(wc);
|
||||||
|
reg |= TIMER_INTERRUPT;
|
||||||
|
}
|
||||||
|
|
||||||
#if DEFERRED_PROCESSING == WORKQUEUE
|
#if DEFERRED_PROCESSING == WORKQUEUE
|
||||||
schedule_work(&wc->deferred_work);
|
schedule_work(&wc->deferred_work);
|
||||||
#elif DEFERRED_PROCESSING == INTERRUPT
|
#elif DEFERRED_PROCESSING == INTERRUPT
|
||||||
@ -3556,14 +3537,6 @@ wctc4xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
setup_timer(&wc->watchdog, wctc4xxp_watchdog, (unsigned long)wc);
|
setup_timer(&wc->watchdog, wctc4xxp_watchdog, (unsigned long)wc);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
|
|
||||||
wc->polling.function = wctc4xxp_polling;
|
|
||||||
wc->polling.data = (unsigned long)wc;
|
|
||||||
init_timer(&wc->polling);
|
|
||||||
# else
|
|
||||||
setup_timer(&wc->polling, wctc4xxp_polling, (unsigned long)wc);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
/* ------------------------------------------------------------------
|
||||||
* Load the firmware and start the DTE.
|
* Load the firmware and start the DTE.
|
||||||
* --------------------------------------------------------------- */
|
* --------------------------------------------------------------- */
|
||||||
@ -3684,9 +3657,6 @@ static void __devexit wctc4xxp_remove_one(struct pci_dev *pdev)
|
|||||||
|
|
||||||
/* This should already be stopped, but it doesn't hurt to make sure. */
|
/* This should already be stopped, but it doesn't hurt to make sure. */
|
||||||
clear_bit(DTE_POLLING, &wc->flags);
|
clear_bit(DTE_POLLING, &wc->flags);
|
||||||
if (del_timer_sync(&wc->polling))
|
|
||||||
del_timer_sync(&wc->polling);
|
|
||||||
|
|
||||||
wctc4xxp_net_unregister(wc);
|
wctc4xxp_net_unregister(wc);
|
||||||
|
|
||||||
/* Stop any DMA */
|
/* Stop any DMA */
|
||||||
|
Loading…
Reference in New Issue
Block a user