diff options
author | citats <citats@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2004-04-06 16:16:01 +0000 |
---|---|---|
committer | citats <citats@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2004-04-06 16:16:01 +0000 |
commit | 5ed80a1de180361db06accab70072e41e7ebd71a (patch) | |
tree | 446d3e2ce18e51a849126db5409def1df2a3d0f6 /wct4xxp.c | |
parent | f457dd454f2179558ca2c6d9e837e680ae8469e4 (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-x | wct4xxp.c | 14 |
1 files changed, 7 insertions, 7 deletions
@@ -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 |