vpmadt032: Remove potential endless waits when resetting.

It is possible to softlock if the board stops delivering interrupts in
the middle of a reset.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9332 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
Shaun Ruffell 2010-09-16 18:57:39 +00:00
parent 844714825a
commit dd98bbda37

View File

@ -564,28 +564,46 @@ int vpmadt032_reset(struct vpmadt032 *vpm)
int res;
gpakPingDspStat_t pingstatus;
u16 version;
unsigned long stoptime;
struct device *const dev = &vpm->vb->pdev->dev;
might_sleep();
set_bit(VPM150M_HPIRESET, &vpm->control);
msleep(2000);
while (test_bit(VPM150M_HPIRESET, &vpm->control))
/* It should never take longer than 5 seconds. */
stoptime = jiffies + 3*HZ;
while (test_bit(VPM150M_HPIRESET, &vpm->control) &&
time_before(jiffies, stoptime))
msleep(1);
if (time_after(jiffies, stoptime)) {
dev_dbg(dev, "Detected failure to clear HPIRESET.\n");
return -EIO;
}
/* Set us up to page 0 */
vpmadt032_setpage(vpm, 0);
res = vpmadtreg_loadfirmware(vpm->vb);
if (res) {
dev_info(&vpm->vb->pdev->dev, "Failed to load the firmware.\n");
dev_err(dev, "Failed to load VPMADT032 firmware.\n");
return res;
}
vpm->curpage = -1;
stoptime = jiffies + 3*HZ;
set_bit(VPM150M_SWRESET, &vpm->control);
while (test_bit(VPM150M_SWRESET, &vpm->control))
while (test_bit(VPM150M_SWRESET, &vpm->control) &&
time_before(jiffies, stoptime))
msleep(1);
if (time_after(jiffies, stoptime)) {
dev_dbg(dev, "Detected failure to clear SWRESET.\n");
return -EIO;
}
/* Set us up to page 0 */
pingstatus = gpakPingDsp(vpm->dspid, &version);
if (!pingstatus) {
@ -606,6 +624,8 @@ vpmadt032_init(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);
@ -616,13 +636,15 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *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(&vpm->vb->pdev->dev, "VPMADT032 Testing page access: ");
dev_info(dev, "VPMADT032 Testing page access: ");
for (i = 0; i < 0xf; i++) {
int x;
@ -630,8 +652,12 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb)
vpmadt032_setpage(vpm, i);
reg = vpmadt032_getpage(vpm);
if (reg != i) {
if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN)
dev_info(&vpm->vb->pdev->dev, "Failed: Sent %x != %x VPMADT032 Failed HI page test\n", i, reg);
if (vpm->options.debug &
DEBUG_VPMADT032_ECHOCAN) {
dev_err(dev, "Failed: Sent %x != %x " \
"VPMADT032 Failed HI page " \
"test\n", i, reg);
}
res = -ENODEV;
goto failed_exit;
}
@ -641,9 +667,17 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb)
if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN)
dev_info(&vpm->vb->pdev->dev, "Passed\n");
stoptime = jiffies + 3*HZ;
set_bit(VPM150M_HPIRESET, &vpm->control);
while (test_bit(VPM150M_HPIRESET, &vpm->control))
while (test_bit(VPM150M_HPIRESET, &vpm->control) &&
time_before(jiffies, stoptime))
msleep(1);
if (time_after(jiffies, stoptime)) {
dev_dbg(dev, "Detected failure to clear HPIRESET.\n");
res = -EIO;
goto failed_exit;
}
msleep(250);
/* Set us up to page 0 */
@ -666,10 +700,18 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb)
if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN)
printk(KERN_CONT "Passed\n");
stoptime = jiffies + 3*HZ;
set_bit(VPM150M_HPIRESET, &vpm->control);
while (test_bit(VPM150M_HPIRESET, &vpm->control))
while (test_bit(VPM150M_HPIRESET, &vpm->control) &&
time_before(jiffies, stoptime))
msleep(1);
if (time_after(jiffies, stoptime)) {
dev_dbg(dev, "Detected failure to clear SWRESET.\n");
res = -EIO;
goto failed_exit;
}
res = vpmadtreg_loadfirmware(vb);
if (res) {
dev_info(&vb->pdev->dev, "Failed to load the firmware.\n");
@ -678,10 +720,19 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb)
vpm->curpage = -1;
dev_info(&vb->pdev->dev, "Booting VPMADT032\n");
stoptime = jiffies + 3*HZ;
set_bit(VPM150M_SWRESET, &vpm->control);
while (test_bit(VPM150M_SWRESET, &vpm->control))
while (test_bit(VPM150M_SWRESET, &vpm->control) &&
time_before(jiffies, stoptime))
msleep(1);
if (time_after(jiffies, stoptime)) {
dev_dbg(dev, "Detected failure to clear SWRESET.\n");
res = -EIO;
goto failed_exit;
}
pingstatus = gpakPingDsp(vpm->dspid, &vpm->version);
if (!pingstatus) {