diff options
Diffstat (limited to 'drivers/dahdi')
-rw-r--r-- | drivers/dahdi/voicebus/GpakCust.c | 81 | ||||
-rw-r--r-- | drivers/dahdi/voicebus/GpakCust.h | 3 | ||||
-rw-r--r-- | drivers/dahdi/wctdm24xxp/base.c | 4 | ||||
-rw-r--r-- | drivers/dahdi/wcte12xp/base.c | 89 |
4 files changed, 125 insertions, 52 deletions
diff --git a/drivers/dahdi/voicebus/GpakCust.c b/drivers/dahdi/voicebus/GpakCust.c index 9a36a2f..ebd60da 100644 --- a/drivers/dahdi/voicebus/GpakCust.c +++ b/drivers/dahdi/voicebus/GpakCust.c @@ -513,6 +513,11 @@ vpmadt032_alloc(struct vpmadt032_options *options) sema_init(&vpm->sem, 1); vpm->curpage = 0x80; vpm->dspid = -1; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&vpm->work, vpmadt032_bh, vpm); +#else + INIT_WORK(&vpm->work, vpmadt032_bh); +#endif /* Do not use the global workqueue for processing these events. Some of * the operations can take 100s of ms, most of that time spent sleeping. @@ -605,36 +610,26 @@ int vpmadt032_reset(struct vpmadt032 *vpm) } EXPORT_SYMBOL(vpmadt032_reset); -int -vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb) +/** + * vpmadt032_test - Check if there is a VPMADT032 present on voicebus device. + * @vpm: Allocated with vpmadt032_alloc previously. + * @vb: Voicebus structure to test on. + * + * Returns 0 if there is a device, otherwise -ENODEV. + * + */ +int vpmadt032_test(struct vpmadt032 *vpm, struct voicebus *vb) { - int i; - u16 reg; - int res = -EFAULT; - unsigned long stoptime; - struct device *dev; - gpakPingDspStat_t pingstatus; - - BUG_ON(!vpm->setchanconfig_from_state); - BUG_ON(!vpm->wq); - BUG_ON(!vb); + u8 reg; + int i, x; + struct device *dev = &vb->pdev->dev; vpm->vb = vb; - might_sleep(); - - dev = &vpm->vb->pdev->dev; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) - INIT_WORK(&vpm->work, vpmadt032_bh, vpm); -#else - INIT_WORK(&vpm->work, vpmadt032_bh); -#endif if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN) dev_info(dev, "VPMADT032 Testing page access: "); for (i = 0; i < 0xf; i++) { - int x; for (x = 0; x < 3; x++) { vpmadt032_setpage(vpm, i); reg = vpmadt032_getpage(vpm); @@ -645,14 +640,42 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb) "VPMADT032 Failed HI page " \ "test\n", i, reg); } - res = -ENODEV; - goto failed_exit; + return -ENODEV; } } } if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN) - dev_info(&vpm->vb->pdev->dev, "Passed\n"); + dev_info(dev, "Passed\n"); + + return 0; +} +EXPORT_SYMBOL(vpmadt032_test); + +/** + * vpmadt032_init - Initialize and load VPMADT032 firmware. + * @vpm: Allocated with vpmadt032_alloc previously. + * + * Returns 0 on success. This must be called after vpmadt032_test already + * checked if there appears to be a VPMADT032 installed on the board. + * + */ +int vpmadt032_init(struct vpmadt032 *vpm) +{ + int i; + u16 reg; + int res = -EFAULT; + unsigned long stoptime; + struct device *dev; + gpakPingDspStat_t pingstatus; + + BUG_ON(!vpm->setchanconfig_from_state); + BUG_ON(!vpm->wq); + BUG_ON(!vpm->vb); + + might_sleep(); + + dev = &vpm->vb->pdev->dev; stoptime = jiffies + 3*HZ; set_bit(VPM150M_HPIRESET, &vpm->control); @@ -699,14 +722,14 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb) goto failed_exit; } - res = vpmadtreg_loadfirmware(vb); + res = vpmadtreg_loadfirmware(vpm->vb); if (res) { - dev_info(&vb->pdev->dev, "Failed to load the firmware.\n"); + dev_info(&vpm->vb->pdev->dev, "Failed to load the firmware.\n"); return res; } vpm->curpage = -1; - dev_info(&vb->pdev->dev, "Booting VPMADT032\n"); + dev_info(&vpm->vb->pdev->dev, "Booting VPMADT032\n"); stoptime = jiffies + 3*HZ; set_bit(VPM150M_SWRESET, &vpm->control); @@ -723,7 +746,7 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb) pingstatus = gpakPingDsp(vpm->dspid, &vpm->version); if (!pingstatus) { - dev_info(&vb->pdev->dev, "VPM present and operational " + dev_info(&vpm->vb->pdev->dev, "VPM present and operational " "(Firmware version %x)\n", vpm->version); } else { dev_notice(&vpm->vb->pdev->dev, "VPMADT032 Failed! Unable to ping the DSP (%d)!\n", pingstatus); diff --git a/drivers/dahdi/voicebus/GpakCust.h b/drivers/dahdi/voicebus/GpakCust.h index bd3308e..758bc28 100644 --- a/drivers/dahdi/voicebus/GpakCust.h +++ b/drivers/dahdi/voicebus/GpakCust.h @@ -137,7 +137,8 @@ struct dahdi_echocanparam; struct dahdi_echocan_state; char vpmadt032tone_to_zaptone(GpakToneCodes_t tone); -int vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb); +int vpmadt032_test(struct vpmadt032 *vpm, struct voicebus *vb); +int vpmadt032_init(struct vpmadt032 *vpm); int vpmadt032_reset(struct vpmadt032 *vpm); struct vpmadt032 *vpmadt032_alloc(struct vpmadt032_options *options); void vpmadt032_free(struct vpmadt032 *vpm); diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c index 03d56e2..7107808 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -3841,7 +3841,9 @@ static int wctdm_initialize_vpmadt032(struct wctdm *wc) /* wc->vpmadt032->context = wc; */ /* Pull the configuration information from the span holding * the analog channels. */ - res = vpmadt032_init(wc->vpmadt032, &wc->vb); + res = vpmadt032_test(wc->vpmadt032, &wc->vb); + if (!res) + res = vpmadt032_init(wc->vpmadt032); if (res) { vpmadt032_free(wc->vpmadt032); wc->vpmadt032 = NULL; diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c index 8698461..6ffb8ba 100644 --- a/drivers/dahdi/wcte12xp/base.c +++ b/drivers/dahdi/wcte12xp/base.c @@ -1385,6 +1385,64 @@ struct vpm_load_work { struct t1 *wc; }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void vpm_load_func(void *data) +{ + struct maint_work_struct *w = data; +#else +static void vpm_load_func(struct work_struct *work) +{ + struct vpm_load_work *w = container_of(work, + struct vpm_load_work, work); +#endif + struct t1 *wc = w->wc; + int res; + + res = vpmadt032_init(wc->vpmadt032); + if (res) { + /* There was some problem during initialization, but it passed + * the address test, let's try again in a bit. */ + wc->vpm_check = jiffies + HZ/2; + return; + } + + if (config_vpmadt032(wc->vpmadt032, wc)) { + clear_bit(VPM150M_ACTIVE, &wc->ctlreg); + wc->vpm_check = jiffies + HZ/2; + return; + } + + /* turn on vpm (RX audio from vpm module) */ + set_bit(VPM150M_ACTIVE, &wc->ctlreg); + wc->vpm_check = jiffies + HZ*5; + if (vpmtsisupport) { + debug_printk(wc, 1, "enabling VPM TSI pin\n"); + /* turn on vpm timeslot interchange pin */ + set_bit(0, &wc->ctlreg); + } + + set_bit(READY, &wc->bit_flags); + kfree(w); +} + +static int vpm_start_load(struct t1 *wc) +{ + struct vpm_load_work *work; + + work = kzalloc(sizeof(*work), GFP_KERNEL); + if (!work) + return -ENOMEM; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&work->work, vpm_load_func, work); +#else + INIT_WORK(&work->work, vpm_load_func); +#endif + work->wc = wc; + + queue_work(wc->wq, &work->work); + return 0; +} + static int check_and_load_vpm(struct t1 *wc) { int res; @@ -1428,7 +1486,7 @@ static int check_and_load_vpm(struct t1 *wc) wc->vpmadt032 = vpm; spin_unlock_irqrestore(&wc->reglock, flags); - res = vpmadt032_init(vpm, &wc->vb); + res = vpmadt032_test(vpm, &wc->vb); if (-ENODEV == res) { struct vpmadt032 *vpm = wc->vpmadt032; @@ -1439,30 +1497,19 @@ static int check_and_load_vpm(struct t1 *wc) spin_unlock_irqrestore(&wc->reglock, flags); vpmadt032_free(vpm); return res; - - } else if (res) { - /* There was some problem during initialization, but it passed - * the address test, let's try again in a bit. */ - wc->vpm_check = jiffies + HZ/2; - return -EAGAIN; } - if (config_vpmadt032(vpm, wc)) { + res = vpm_start_load(wc); + if (res) { + /* There does not appear to be a VPMADT032 installed. */ clear_bit(VPM150M_ACTIVE, &wc->ctlreg); - wc->vpm_check = jiffies + HZ/2; - return -EAGAIN; - } - - /* turn on vpm (RX audio from vpm module) */ - set_bit(VPM150M_ACTIVE, &wc->ctlreg); - wc->vpm_check = jiffies + HZ*5; - if (vpmtsisupport) { - debug_printk(wc, 1, "enabling VPM TSI pin\n"); - /* turn on vpm timeslot interchange pin */ - set_bit(0, &wc->ctlreg); + spin_lock_irqsave(&wc->reglock, flags); + wc->vpmadt032 = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + vpmadt032_free(vpm); + return res; } - - return 0; + return res; } #else static inline int check_and_load_vpm(const struct t1 *wc) |