diff options
author | David Vrabel <david.vrabel@csr.com> | 2008-11-07 12:37:33 -0500 |
---|---|---|
committer | David Vrabel <david.vrabel@csr.com> | 2008-11-07 12:37:33 -0500 |
commit | 307ba6dd73254fe7d2ce27db64ffd90e1bb3c6c0 (patch) | |
tree | 535e10e6bd399c1f1d1f55a546e0c6aa92ba9dee /drivers/uwb/whc-rc.c | |
parent | fec1a5932f16c0eb1b3f5ca2e18d81d860924088 (diff) |
uwb: don't unbind the radio controller driver when resetting
Use pre_reset and post_reset methods to avoid unbinding the radio
controller driver after a uwb_rc_reset_all() call. This avoids a
deadlock in uwb_rc_rm() when waiting for the uwb event thread to stop.
Signed-off-by: David Vrabel <david.vrabel@csr.com>
Diffstat (limited to 'drivers/uwb/whc-rc.c')
-rw-r--r-- | drivers/uwb/whc-rc.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c index 6c454eadd307..e0d66938ccd8 100644 --- a/drivers/uwb/whc-rc.c +++ b/drivers/uwb/whc-rc.c | |||
@@ -394,7 +394,7 @@ void whcrc_stop_rc(struct uwb_rc *rc) | |||
394 | 394 | ||
395 | le_writel(0, whcrc->rc_base + URCCMD); | 395 | le_writel(0, whcrc->rc_base + URCCMD); |
396 | whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS, | 396 | whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS, |
397 | URCSTS_HALTED, 0, 40, "URCSTS.HALTED"); | 397 | URCSTS_HALTED, URCSTS_HALTED, 100, "URCSTS.HALTED"); |
398 | } | 398 | } |
399 | 399 | ||
400 | static void whcrc_init(struct whcrc *whcrc) | 400 | static void whcrc_init(struct whcrc *whcrc) |
@@ -488,6 +488,24 @@ static void whcrc_remove(struct umc_dev *umc_dev) | |||
488 | d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc); | 488 | d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc); |
489 | } | 489 | } |
490 | 490 | ||
491 | static int whcrc_pre_reset(struct umc_dev *umc) | ||
492 | { | ||
493 | struct whcrc *whcrc = umc_get_drvdata(umc); | ||
494 | struct uwb_rc *uwb_rc = whcrc->uwb_rc; | ||
495 | |||
496 | uwb_rc_pre_reset(uwb_rc); | ||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | static int whcrc_post_reset(struct umc_dev *umc) | ||
501 | { | ||
502 | struct whcrc *whcrc = umc_get_drvdata(umc); | ||
503 | struct uwb_rc *uwb_rc = whcrc->uwb_rc; | ||
504 | |||
505 | uwb_rc_post_reset(uwb_rc); | ||
506 | return 0; | ||
507 | } | ||
508 | |||
491 | /* PCI device ID's that we handle [so it gets loaded] */ | 509 | /* PCI device ID's that we handle [so it gets loaded] */ |
492 | static struct pci_device_id whcrc_id_table[] = { | 510 | static struct pci_device_id whcrc_id_table[] = { |
493 | { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) }, | 511 | { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) }, |
@@ -496,10 +514,12 @@ static struct pci_device_id whcrc_id_table[] = { | |||
496 | MODULE_DEVICE_TABLE(pci, whcrc_id_table); | 514 | MODULE_DEVICE_TABLE(pci, whcrc_id_table); |
497 | 515 | ||
498 | static struct umc_driver whcrc_driver = { | 516 | static struct umc_driver whcrc_driver = { |
499 | .name = "whc-rc", | 517 | .name = "whc-rc", |
500 | .cap_id = UMC_CAP_ID_WHCI_RC, | 518 | .cap_id = UMC_CAP_ID_WHCI_RC, |
501 | .probe = whcrc_probe, | 519 | .probe = whcrc_probe, |
502 | .remove = whcrc_remove, | 520 | .remove = whcrc_remove, |
521 | .pre_reset = whcrc_pre_reset, | ||
522 | .post_reset = whcrc_post_reset, | ||
503 | }; | 523 | }; |
504 | 524 | ||
505 | static int __init whcrc_driver_init(void) | 525 | static int __init whcrc_driver_init(void) |