summaryrefslogtreecommitdiff
path: root/wct4xxp.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2004-04-09 17:19:57 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2004-04-09 17:19:57 +0000
commitd5698fc0ee052b080dd3586d296f93d5d668e32b (patch)
tree86838c1ad631bea50ce9366f6f6d54bc89051bba /wct4xxp.c
parentb7aa56683a7bd657063cf88021542c94bc842d05 (diff)
Check once a second for a new timing source (bug #1397)
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@353 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wct4xxp.c')
-rwxr-xr-xwct4xxp.c50
1 files changed, 34 insertions, 16 deletions
diff --git a/wct4xxp.c b/wct4xxp.c
index 03d9f06..3563880 100755
--- a/wct4xxp.c
+++ b/wct4xxp.c
@@ -143,7 +143,7 @@ static int t4_rbsbits(struct zt_chan *chan, int bits);
static int t4_maint(struct zt_span *span, int cmd);
static int t4_reset_dma(struct t4 *wc);
static int t4_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data);
-static void t4_set_timing_source_auto(struct t4 *wc);
+static void __t4_set_timing_source_auto(struct t4 *wc);
#define WC_RDADDR 0
#define WC_WRADDR 1
@@ -464,7 +464,9 @@ static int t4_shutdown(struct zt_span *span)
__t4_pci_out(wc, WC_DMACTRL, 0x00000000);
/* Acknowledge any pending interrupts */
__t4_pci_out(wc, WC_INTR, 0x00000000);
- }
+ __t4_set_timing_source_auto(wc);
+ } else
+ wc->checktiming = 1;
spin_unlock_irqrestore(&wc->reglock, flags);
if (debug)
printk("Span %d (%s) shutdown\n", span->spanno, span->name);
@@ -629,10 +631,11 @@ static void t4_serial_setup(struct t4 *wc, int unit)
printk("Successfully initialized serial bus for unit %d\n", unit);
}
-static void t4_set_timing_source(struct t4 *wc, int unit)
+static void __t4_set_timing_source(struct t4 *wc, int unit)
{
unsigned int timing;
int x;
+ int updated = 0;
wc->checktiming = 0;
timing = 0x34; /* CMR1: RCLK unit, 8.192 Mhz TCLK, RCLK is 8.192 Mhz */
if (unit != wc->syncsrc) {
@@ -642,17 +645,14 @@ static void t4_set_timing_source(struct t4 *wc, int unit)
timing |= 0x1; /* Use TCLK timing */
}
for (x=0;x<4;x++)
- t4_framer_out(wc, x, 0x44, timing);
+ __t4_framer_out(wc, x, 0x44, timing);
if ((unit > -1) && (unit < 4)) {
- t4_pci_out(wc, WC_DMACTRL, wc->dmactrl | (1 << 29));
+ __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl | (1 << 29));
/* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from proper channel, */
- t4_framer_out(wc, 0, 0x85, 0xe0 | (unit << 2) | (unit));
+ __t4_framer_out(wc, 0, 0x85, 0xe0 | (unit << 2) | (unit));
} else
- t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
- if ((unit > -1) && (unit < 4))
- printk("TE410P: Timing from span %d\n", unit + 1);
- else
- printk("TE410P: Timing from internal timer\n");
+ __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
+ updated = 1;
}
wc->syncsrc = unit;
if ((unit < 0) || (unit > 3))
@@ -661,9 +661,15 @@ static void t4_set_timing_source(struct t4 *wc, int unit)
unit++;
for (x=0;x<4;x++)
wc->spans[x].syncsrc = unit;
+ if (updated) {
+ if (unit)
+ printk("TE410P: Timing from span %d\n", unit);
+ else
+ printk("TE410P: Timing from internal timer\n");
+ }
}
-static void t4_set_timing_source_auto(struct t4 *wc)
+static void __t4_set_timing_source_auto(struct t4 *wc)
{
int x;
for (x=0;x<4;x++) {
@@ -671,12 +677,20 @@ static void t4_set_timing_source_auto(struct t4 *wc)
if ((wc->spans[wc->syncs[x] - 1].flags & ZT_FLAG_RUNNING) &&
!(wc->spans[wc->syncs[x] - 1].alarms)) {
/* Valid timing sourc e*/
- t4_set_timing_source(wc, wc->syncs[x] - 1);
+ __t4_set_timing_source(wc, wc->syncs[x] - 1);
return;
}
}
}
- t4_set_timing_source(wc, 4);
+ __t4_set_timing_source(wc, 4);
+}
+
+static void t4_set_timing_source_auto(struct t4 *wc)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&wc->reglock, flags);
+ __t4_set_timing_source_auto(wc);
+ spin_unlock_irqrestore(&wc->reglock, flags);
}
static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlevel)
@@ -1451,10 +1465,14 @@ static void t4_interrupt(int irq, void *dev_id, struct pt_regs *regs)
__t4_check_alarms(wc, x - 4);
break;
}
+
+ /* periodically check timing */
+ if (!(wc->intcount % (8000/ZT_CHUNKSIZE)))
+ wc->checktiming = 1;
- spin_unlock_irqrestore(&wc->reglock, flags);
if (wc->checktiming > 0)
- t4_set_timing_source_auto(wc);
+ __t4_set_timing_source_auto(wc);
+ spin_unlock_irqrestore(&wc->reglock, flags);
#ifdef LINUX26
return IRQ_RETVAL(1);
#endif