aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hardware/mISDN/hfcmulti.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/hardware/mISDN/hfcmulti.c')
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 3fc2e9d95341..592db93105f9 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -133,6 +133,12 @@
133 * Give the value of the clock control register (A_ST_CLK_DLY) 133 * Give the value of the clock control register (A_ST_CLK_DLY)
134 * of the S/T interfaces in TE mode. 134 * of the S/T interfaces in TE mode.
135 * This register is needed for the TBR3 certification, so don't change it. 135 * This register is needed for the TBR3 certification, so don't change it.
136 *
137 * clock:
138 * NOTE: only one clockdelay_te value must be given once
139 * Selects interface with clock source for mISDN and applications.
140 * Set to card number starting with 1. Set to -1 to disable.
141 * By default, the first card is used as clock source.
136 */ 142 */
137 143
138/* 144/*
@@ -190,12 +196,13 @@ static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 };
190 */ 196 */
191 197
192static uint type[MAX_CARDS]; 198static uint type[MAX_CARDS];
193static uint pcm[MAX_CARDS]; 199static int pcm[MAX_CARDS];
194static uint dslot[MAX_CARDS]; 200static int dslot[MAX_CARDS];
195static uint iomode[MAX_CARDS]; 201static uint iomode[MAX_CARDS];
196static uint port[MAX_PORTS]; 202static uint port[MAX_PORTS];
197static uint debug; 203static uint debug;
198static uint poll; 204static uint poll;
205static int clock;
199static uint timer; 206static uint timer;
200static uint clockdelay_te = CLKDEL_TE; 207static uint clockdelay_te = CLKDEL_TE;
201static uint clockdelay_nt = CLKDEL_NT; 208static uint clockdelay_nt = CLKDEL_NT;
@@ -207,12 +214,13 @@ MODULE_LICENSE("GPL");
207MODULE_VERSION(HFC_MULTI_VERSION); 214MODULE_VERSION(HFC_MULTI_VERSION);
208module_param(debug, uint, S_IRUGO | S_IWUSR); 215module_param(debug, uint, S_IRUGO | S_IWUSR);
209module_param(poll, uint, S_IRUGO | S_IWUSR); 216module_param(poll, uint, S_IRUGO | S_IWUSR);
217module_param(clock, int, S_IRUGO | S_IWUSR);
210module_param(timer, uint, S_IRUGO | S_IWUSR); 218module_param(timer, uint, S_IRUGO | S_IWUSR);
211module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR); 219module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR);
212module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR); 220module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR);
213module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR); 221module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);
214module_param_array(pcm, uint, NULL, S_IRUGO | S_IWUSR); 222module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR);
215module_param_array(dslot, uint, NULL, S_IRUGO | S_IWUSR); 223module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR);
216module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR); 224module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR);
217module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); 225module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
218 226
@@ -2629,6 +2637,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
2629 iqcnt = 0; 2637 iqcnt = 0;
2630 } 2638 }
2631#endif 2639#endif
2640
2632 if (!r_irq_statech && 2641 if (!r_irq_statech &&
2633 !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA | 2642 !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA |
2634 V_MISC_IRQSTA | V_FR_IRQSTA))) { 2643 V_MISC_IRQSTA | V_FR_IRQSTA))) {
@@ -2683,11 +2692,13 @@ hfcmulti_interrupt(int intno, void *dev_id)
2683 plxsd_checksync(hc, 0); 2692 plxsd_checksync(hc, 0);
2684 } 2693 }
2685 } 2694 }
2686 if (r_irq_misc & V_TI_IRQ) 2695 if (r_irq_misc & V_TI_IRQ) {
2696 if (hc->iclock_on)
2697 mISDN_clock_update(hc->iclock, poll, NULL);
2687 handle_timer_irq(hc); 2698 handle_timer_irq(hc);
2699 }
2688 2700
2689 if (r_irq_misc & V_DTMF_IRQ) { 2701 if (r_irq_misc & V_DTMF_IRQ) {
2690 /* -> DTMF IRQ */
2691 hfcmulti_dtmf(hc); 2702 hfcmulti_dtmf(hc);
2692 } 2703 }
2693 if (r_irq_misc & V_IRQ_PROC) { 2704 if (r_irq_misc & V_IRQ_PROC) {
@@ -4075,6 +4086,15 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
4075 return err; 4086 return err;
4076} 4087}
4077 4088
4089static int
4090clockctl(void *priv, int enable)
4091{
4092 struct hfc_multi *hc = priv;
4093
4094 hc->iclock_on = enable;
4095 return 0;
4096}
4097
4078/* 4098/*
4079 * initialize the card 4099 * initialize the card
4080 */ 4100 */
@@ -4489,10 +4509,14 @@ release_card(struct hfc_multi *hc)
4489 printk(KERN_WARNING "%s: release card (%d) entered\n", 4509 printk(KERN_WARNING "%s: release card (%d) entered\n",
4490 __func__, hc->id); 4510 __func__, hc->id);
4491 4511
4512 /* unregister clock source */
4513 if (hc->iclock)
4514 mISDN_unregister_clock(hc->iclock);
4515
4516 /* disable irq */
4492 spin_lock_irqsave(&hc->lock, flags); 4517 spin_lock_irqsave(&hc->lock, flags);
4493 disable_hwirq(hc); 4518 disable_hwirq(hc);
4494 spin_unlock_irqrestore(&hc->lock, flags); 4519 spin_unlock_irqrestore(&hc->lock, flags);
4495
4496 udelay(1000); 4520 udelay(1000);
4497 4521
4498 /* dimm leds */ 4522 /* dimm leds */
@@ -5003,6 +5027,10 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
5003 list_add_tail(&hc->list, &HFClist); 5027 list_add_tail(&hc->list, &HFClist);
5004 spin_unlock_irqrestore(&HFClock, flags); 5028 spin_unlock_irqrestore(&HFClock, flags);
5005 5029
5030 /* use as clock source */
5031 if (clock == HFC_cnt + 1)
5032 hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc);
5033
5006 /* initialize hardware */ 5034 /* initialize hardware */
5007 ret_err = init_card(hc); 5035 ret_err = init_card(hc);
5008 if (ret_err) { 5036 if (ret_err) {
@@ -5273,6 +5301,9 @@ HFCmulti_init(void)
5273 5301
5274 } 5302 }
5275 5303
5304 if (!clock)
5305 clock = 1;
5306
5276 err = pci_register_driver(&hfcmultipci_driver); 5307 err = pci_register_driver(&hfcmultipci_driver);
5277 if (err < 0) { 5308 if (err < 0) {
5278 printk(KERN_ERR "error registering pci driver: %x\n", err); 5309 printk(KERN_ERR "error registering pci driver: %x\n", err);