diff options
author | James Hogan <james@albanarts.com> | 2010-10-16 21:48:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-21 07:25:50 -0400 |
commit | afed4ccb0d975f1d3c98880ecf19a24f3d842394 (patch) | |
tree | 833c9663cc409846f17d180efa88c4098d474651 /drivers/net/b44.c | |
parent | 31b9c19bfe32bed7fdf80cd0b1aa9d0f0569844a (diff) |
b44: fix resume, request_irq after hw reset
On resume, call request_irq() after resetting the hardware rather than
before. It's a shared interrupt so the handler could be called
immediately if another device on the same irq interrupts (and will be
called immediately if CONFIG_DEBUG_SHIRQ=y), but unless the hardware is
reinitialised with b44_init_hw() the read of the interrupt status
register will hang the system.
Signed-off-by: James Hogan <james@albanarts.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/b44.c')
-rw-r--r-- | drivers/net/b44.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 8e7c8a8e61c7..171da7f75108 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -2296,18 +2296,27 @@ static int b44_resume(struct ssb_device *sdev) | |||
2296 | if (!netif_running(dev)) | 2296 | if (!netif_running(dev)) |
2297 | return 0; | 2297 | return 0; |
2298 | 2298 | ||
2299 | spin_lock_irq(&bp->lock); | ||
2300 | b44_init_rings(bp); | ||
2301 | b44_init_hw(bp, B44_FULL_RESET); | ||
2302 | spin_unlock_irq(&bp->lock); | ||
2303 | |||
2304 | /* | ||
2305 | * As a shared interrupt, the handler can be called immediately. To be | ||
2306 | * able to check the interrupt status the hardware must already be | ||
2307 | * powered back on (b44_init_hw). | ||
2308 | */ | ||
2299 | rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev); | 2309 | rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev); |
2300 | if (rc) { | 2310 | if (rc) { |
2301 | netdev_err(dev, "request_irq failed\n"); | 2311 | netdev_err(dev, "request_irq failed\n"); |
2312 | spin_lock_irq(&bp->lock); | ||
2313 | b44_halt(bp); | ||
2314 | b44_free_rings(bp); | ||
2315 | spin_unlock_irq(&bp->lock); | ||
2302 | return rc; | 2316 | return rc; |
2303 | } | 2317 | } |
2304 | 2318 | ||
2305 | spin_lock_irq(&bp->lock); | ||
2306 | |||
2307 | b44_init_rings(bp); | ||
2308 | b44_init_hw(bp, B44_FULL_RESET); | ||
2309 | netif_device_attach(bp->dev); | 2319 | netif_device_attach(bp->dev); |
2310 | spin_unlock_irq(&bp->lock); | ||
2311 | 2320 | ||
2312 | b44_enable_ints(bp); | 2321 | b44_enable_ints(bp); |
2313 | netif_wake_queue(dev); | 2322 | netif_wake_queue(dev); |