wcte12xp, wctdm24xxp: Separate test for VPMADT032 and initialization.
Part of increasing system startup speed. Splitting these two operations facilitate checking if there is a module present synchronously on driver load from the actual load of the firmware and configuration of the channels. This will allow the presence of the VPM module to be flagged on the span before registration, but load and configuration can happen in the background. When the modules are eventually loaded via udev, there will be enough time from the time the drivers are loaded to when dahdi_cfg will run to complete the firmware load, eliminating the need to block the driver here. Signed-off-by: Shaun Ruffell <sruffell@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9951 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
parent
205847da8e
commit
77dfe92f26
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
spin_lock_irqsave(&wc->reglock, flags);
|
||||
wc->vpmadt032 = NULL;
|
||||
spin_unlock_irqrestore(&wc->reglock, flags);
|
||||
vpmadt032_free(vpm);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
static inline int check_and_load_vpm(const struct t1 *wc)
|
||||
|
|
Loading…
Reference in New Issue