summaryrefslogtreecommitdiff
path: root/drivers/dahdi/wctdm24xxp/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dahdi/wctdm24xxp/base.c')
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index 012b5b8..637cda2 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -1526,7 +1526,14 @@ wctdm_proslic_verify_indirect_regs(struct wctdm *wc, struct wctdm_module *mod)
return 0;
}
-/* 1ms interrupt */
+/**
+ * wctdm_proslic_check_oppending -
+ *
+ * Ensures that a write to the line feed register on the SLIC has been
+ * processed. If it hasn't after the timeout value, then it will resend the
+ * command and wait for another timeout period.
+ *
+ */
static void
wctdm_proslic_check_oppending(struct wctdm *wc, struct wctdm_module *const mod)
{
@@ -1546,7 +1553,6 @@ wctdm_proslic_check_oppending(struct wctdm *wc, struct wctdm_module *const mod)
if ((fxs->linefeed_control_shadow & SLIC_LF_SETMASK) ==
(fxs->lasttxhook & SLIC_LF_SETMASK)) {
fxs->lasttxhook &= SLIC_LF_SETMASK;
- fxs->oppending_ms = 0;
if (debug & DEBUG_CARD) {
dev_info(&wc->vb.pdev->dev,
"SLIC_LF OK: card=%d shadow=%02x "
@@ -1554,7 +1560,12 @@ wctdm_proslic_check_oppending(struct wctdm *wc, struct wctdm_module *const mod)
fxs->linefeed_control_shadow,
fxs->lasttxhook, wc->framecount);
}
- } else if (fxs->oppending_ms && (--fxs->oppending_ms == 0)) {
+ spin_unlock(&fxs->lasttxhooklock);
+ } else if (time_after(wc->framecount, fxs->oppending_timeout)) {
+ /* Check again in 100 ms */
+ fxs->oppending_timeout = wc->framecount + 100;
+ spin_unlock(&fxs->lasttxhooklock);
+
wctdm_setreg_intr(wc, mod, LINE_STATE, fxs->lasttxhook);
if (debug & DEBUG_CARD) {
dev_info(&wc->vb.pdev->dev,
@@ -1563,10 +1574,9 @@ wctdm_proslic_check_oppending(struct wctdm *wc, struct wctdm_module *const mod)
fxs->linefeed_control_shadow,
fxs->lasttxhook, wc->framecount);
}
- } else { /* Start 100ms Timeout */
- fxs->oppending_ms = 100;
+ } else {
+ spin_unlock(&fxs->lasttxhooklock);
}
- spin_unlock(&fxs->lasttxhooklock);
}
/* 256ms interrupt */
@@ -1635,6 +1645,7 @@ wctdm_proslic_recheck_sanity(struct wctdm *wc, struct wctdm_module *const mod)
}
fxs->lasttxhook |= SLIC_LF_OPPENDING;
mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook);
+ fxs->oppending_timeout = wc->framecount + 100;
spin_unlock_irqrestore(&fxs->lasttxhooklock, flags);
/* Update shadow register to avoid extra power alarms
@@ -2065,6 +2076,7 @@ wctdm_fxs_hooksig(struct wctdm *wc, struct wctdm_module *const mod,
if (x != fxs->lasttxhook) {
fxs->lasttxhook = x | SLIC_LF_OPPENDING;
mod->sethook = CMD_WR(LINE_STATE, fxs->lasttxhook);
+ fxs->oppending_timeout = wc->framecount + 100;
spin_unlock_irqrestore(&fxs->lasttxhooklock, flags);
if (debug & DEBUG_CARD) {