summaryrefslogtreecommitdiff
path: root/wct4xxp.c
diff options
context:
space:
mode:
authorcitats <citats@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2004-04-06 16:16:01 +0000
committercitats <citats@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2004-04-06 16:16:01 +0000
commit5ed80a1de180361db06accab70072e41e7ebd71a (patch)
tree446d3e2ce18e51a849126db5409def1df2a3d0f6 /wct4xxp.c
parentf457dd454f2179558ca2c6d9e837e680ae8469e4 (diff)
Really fix deadlock on SMP systems with TE410P and new timing
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@345 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wct4xxp.c')
-rwxr-xr-xwct4xxp.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/wct4xxp.c b/wct4xxp.c
index 83dd8f4..7c43684 100755
--- a/wct4xxp.c
+++ b/wct4xxp.c
@@ -133,6 +133,7 @@ struct t4 {
unsigned int passno; /* number of interrupt passes */
char *variety;
int last0; /* for detecting double-missed IRQ */
+ int checktiming; /* Set >0 to cause the timing source to be checked */
};
static void __set_clear(struct t4 *wc, int span);
@@ -628,15 +629,12 @@ static void t4_serial_setup(struct t4 *wc, int unit)
printk("Successfully initialized serial bus for unit %d\n", unit);
}
-static spinlock_t synclock = SPIN_LOCK_UNLOCKED;
-
static void t4_set_timing_source(struct t4 *wc, int unit)
{
unsigned int timing;
- unsigned long flags;
int x;
+ wc->checktiming = 0;
timing = 0x34; /* CMR1: RCLK unit, 8.192 Mhz TCLK, RCLK is 8.192 Mhz */
- spin_lock_irqsave(&synclock, flags);
if (unit != wc->syncsrc) {
if ((unit > -1) && (unit < 4)) {
timing |= (unit << 6);
@@ -663,7 +661,6 @@ static void t4_set_timing_source(struct t4 *wc, int unit)
for (x=0;x<4;x++)
wc->spans[x].syncsrc = unit;
}
- spin_unlock_irqrestore(&synclock, flags);
}
static void t4_set_timing_source_auto(struct t4 *wc)
@@ -1171,7 +1168,7 @@ static void __t4_do_counters(struct t4 *wc)
if (wc->alarmtimer[span]) {
if (!--wc->alarmtimer[span]) {
wc->spans[span].alarms &= ~(ZT_ALARM_RECOVER);
- t4_set_timing_source_auto(wc);
+ wc->checktiming = 1;
zt_alarm_notify(&wc->spans[span]);
}
}
@@ -1304,7 +1301,7 @@ static void __t4_check_alarms(struct t4 *wc, int span)
oldalarms &= ~ZT_ALARM_YELLOW;
alarms &= ~ZT_ALARM_YELLOW;
if ((!oldalarms && alarms) || (oldalarms && !alarms))
- t4_set_timing_source_auto(wc);
+ wc->checktiming = 1;
zt_alarm_notify(&wc->spans[span]);
}
@@ -1456,6 +1453,8 @@ static void t4_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
spin_unlock_irqrestore(&wc->reglock, flags);
+ if (wc->checktiming > 0)
+ t4_set_timing_source_auto(wc);
#ifdef LINUX26
return IRQ_RETVAL(1);
#endif
@@ -1592,6 +1591,7 @@ static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_i
wc->memaddr = pci_resource_start(pdev, 0);
wc->memlen = pci_resource_len(pdev, 0);
wc->membase = ioremap(wc->memaddr, wc->memlen);
+ wc->checktiming = 0;
/* This rids of the Double missed interrupt message after loading */
wc->last0 = 1;
#if 0