aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2018-01-10 10:32:10 -0500
committerMarcel Holtmann <marcel@holtmann.org>2018-01-10 13:00:13 -0500
commit8bfa7e1e03aca3626b82857850a1e18ae0ed291d (patch)
tree5a9c893366926985757accf5fdcf5c034857164e
parent8353b4a636f2c83de748656acc6b6a8757d7a0ff (diff)
Bluetooth: hci_bcm: Handle errors properly
A significant portion of this driver lacks error handling. As a first step, add error paths to bcm_gpio_set_power(), bcm_open(), bcm_close(), bcm_suspend_device(), bcm_resume_device(), bcm_resume(), bcm_probe() and bcm_serdev_probe(). (I've also scrutinized bcm_suspend() but think it's fine as is.) Those are all the functions accessing the device wake and shutdown GPIO. On Apple Macs the pins are accessed through ACPI methods, which may fail for various reasons, hence proper error handling is necessary. Non-Macs access the pins directly, which may fail as well but the GPIO core does not yet pass back errors to consumers. Cc: Frédéric Danis <frederic.danis.oss@gmail.com> Cc: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--drivers/bluetooth/hci_bcm.c91
1 files changed, 75 insertions, 16 deletions
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index 8741e302e6fd..03a365148184 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -197,11 +197,21 @@ static bool bcm_device_exists(struct bcm_device *device)
197 197
198static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) 198static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
199{ 199{
200 if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled) 200 int err;
201 clk_prepare_enable(dev->clk);
202 201
203 dev->set_shutdown(dev, powered); 202 if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled) {
204 dev->set_device_wakeup(dev, powered); 203 err = clk_prepare_enable(dev->clk);
204 if (err)
205 return err;
206 }
207
208 err = dev->set_shutdown(dev, powered);
209 if (err)
210 goto err_clk_disable;
211
212 err = dev->set_device_wakeup(dev, powered);
213 if (err)
214 goto err_revert_shutdown;
205 215
206 if (!powered && !IS_ERR(dev->clk) && dev->clk_enabled) 216 if (!powered && !IS_ERR(dev->clk) && dev->clk_enabled)
207 clk_disable_unprepare(dev->clk); 217 clk_disable_unprepare(dev->clk);
@@ -209,6 +219,13 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
209 dev->clk_enabled = powered; 219 dev->clk_enabled = powered;
210 220
211 return 0; 221 return 0;
222
223err_revert_shutdown:
224 dev->set_shutdown(dev, !powered);
225err_clk_disable:
226 if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled)
227 clk_disable_unprepare(dev->clk);
228 return err;
212} 229}
213 230
214#ifdef CONFIG_PM 231#ifdef CONFIG_PM
@@ -331,6 +348,7 @@ static int bcm_open(struct hci_uart *hu)
331{ 348{
332 struct bcm_data *bcm; 349 struct bcm_data *bcm;
333 struct list_head *p; 350 struct list_head *p;
351 int err;
334 352
335 bt_dev_dbg(hu->hdev, "hu %p", hu); 353 bt_dev_dbg(hu->hdev, "hu %p", hu);
336 354
@@ -345,7 +363,10 @@ static int bcm_open(struct hci_uart *hu)
345 mutex_lock(&bcm_device_lock); 363 mutex_lock(&bcm_device_lock);
346 364
347 if (hu->serdev) { 365 if (hu->serdev) {
348 serdev_device_open(hu->serdev); 366 err = serdev_device_open(hu->serdev);
367 if (err)
368 goto err_free;
369
349 bcm->dev = serdev_device_get_drvdata(hu->serdev); 370 bcm->dev = serdev_device_get_drvdata(hu->serdev);
350 goto out; 371 goto out;
351 } 372 }
@@ -373,17 +394,30 @@ out:
373 if (bcm->dev) { 394 if (bcm->dev) {
374 hu->init_speed = bcm->dev->init_speed; 395 hu->init_speed = bcm->dev->init_speed;
375 hu->oper_speed = bcm->dev->oper_speed; 396 hu->oper_speed = bcm->dev->oper_speed;
376 bcm_gpio_set_power(bcm->dev, true); 397 err = bcm_gpio_set_power(bcm->dev, true);
398 if (err)
399 goto err_unset_hu;
377 } 400 }
378 401
379 mutex_unlock(&bcm_device_lock); 402 mutex_unlock(&bcm_device_lock);
380 return 0; 403 return 0;
404
405err_unset_hu:
406#ifdef CONFIG_PM
407 bcm->dev->hu = NULL;
408#endif
409err_free:
410 mutex_unlock(&bcm_device_lock);
411 hu->priv = NULL;
412 kfree(bcm);
413 return err;
381} 414}
382 415
383static int bcm_close(struct hci_uart *hu) 416static int bcm_close(struct hci_uart *hu)
384{ 417{
385 struct bcm_data *bcm = hu->priv; 418 struct bcm_data *bcm = hu->priv;
386 struct bcm_device *bdev = NULL; 419 struct bcm_device *bdev = NULL;
420 int err;
387 421
388 bt_dev_dbg(hu->hdev, "hu %p", hu); 422 bt_dev_dbg(hu->hdev, "hu %p", hu);
389 423
@@ -407,8 +441,11 @@ static int bcm_close(struct hci_uart *hu)
407 pm_runtime_disable(bdev->dev); 441 pm_runtime_disable(bdev->dev);
408 } 442 }
409 443
410 bcm_gpio_set_power(bdev, false); 444 err = bcm_gpio_set_power(bdev, false);
411 pm_runtime_set_suspended(bdev->dev); 445 if (err)
446 bt_dev_err(hu->hdev, "Failed to power down");
447 else
448 pm_runtime_set_suspended(bdev->dev);
412 } 449 }
413 mutex_unlock(&bcm_device_lock); 450 mutex_unlock(&bcm_device_lock);
414 451
@@ -588,6 +625,7 @@ static struct sk_buff *bcm_dequeue(struct hci_uart *hu)
588static int bcm_suspend_device(struct device *dev) 625static int bcm_suspend_device(struct device *dev)
589{ 626{
590 struct bcm_device *bdev = dev_get_drvdata(dev); 627 struct bcm_device *bdev = dev_get_drvdata(dev);
628 int err;
591 629
592 bt_dev_dbg(bdev, ""); 630 bt_dev_dbg(bdev, "");
593 631
@@ -599,7 +637,15 @@ static int bcm_suspend_device(struct device *dev)
599 } 637 }
600 638
601 /* Suspend the device */ 639 /* Suspend the device */
602 bdev->set_device_wakeup(bdev, false); 640 err = bdev->set_device_wakeup(bdev, false);
641 if (err) {
642 if (bdev->is_suspended && bdev->hu) {
643 bdev->is_suspended = false;
644 hci_uart_set_flow_control(bdev->hu, false);
645 }
646 return -EBUSY;
647 }
648
603 bt_dev_dbg(bdev, "suspend, delaying 15 ms"); 649 bt_dev_dbg(bdev, "suspend, delaying 15 ms");
604 mdelay(15); 650 mdelay(15);
605 651
@@ -609,10 +655,16 @@ static int bcm_suspend_device(struct device *dev)
609static int bcm_resume_device(struct device *dev) 655static int bcm_resume_device(struct device *dev)
610{ 656{
611 struct bcm_device *bdev = dev_get_drvdata(dev); 657 struct bcm_device *bdev = dev_get_drvdata(dev);
658 int err;
612 659
613 bt_dev_dbg(bdev, ""); 660 bt_dev_dbg(bdev, "");
614 661
615 bdev->set_device_wakeup(bdev, true); 662 err = bdev->set_device_wakeup(bdev, true);
663 if (err) {
664 dev_err(dev, "Failed to power up\n");
665 return err;
666 }
667
616 bt_dev_dbg(bdev, "resume, delaying 15 ms"); 668 bt_dev_dbg(bdev, "resume, delaying 15 ms");
617 mdelay(15); 669 mdelay(15);
618 670
@@ -666,6 +718,7 @@ unlock:
666static int bcm_resume(struct device *dev) 718static int bcm_resume(struct device *dev)
667{ 719{
668 struct bcm_device *bdev = dev_get_drvdata(dev); 720 struct bcm_device *bdev = dev_get_drvdata(dev);
721 int err = 0;
669 722
670 bt_dev_dbg(bdev, "resume: is_suspended %d", bdev->is_suspended); 723 bt_dev_dbg(bdev, "resume: is_suspended %d", bdev->is_suspended);
671 724
@@ -685,14 +738,16 @@ static int bcm_resume(struct device *dev)
685 bt_dev_dbg(bdev, "BCM irq: disabled"); 738 bt_dev_dbg(bdev, "BCM irq: disabled");
686 } 739 }
687 740
688 bcm_resume_device(dev); 741 err = bcm_resume_device(dev);
689 742
690unlock: 743unlock:
691 mutex_unlock(&bcm_device_lock); 744 mutex_unlock(&bcm_device_lock);
692 745
693 pm_runtime_disable(dev); 746 if (!err) {
694 pm_runtime_set_active(dev); 747 pm_runtime_disable(dev);
695 pm_runtime_enable(dev); 748 pm_runtime_set_active(dev);
749 pm_runtime_enable(dev);
750 }
696 751
697 return 0; 752 return 0;
698} 753}
@@ -923,7 +978,9 @@ static int bcm_probe(struct platform_device *pdev)
923 list_add_tail(&dev->list, &bcm_device_list); 978 list_add_tail(&dev->list, &bcm_device_list);
924 mutex_unlock(&bcm_device_lock); 979 mutex_unlock(&bcm_device_lock);
925 980
926 bcm_gpio_set_power(dev, false); 981 ret = bcm_gpio_set_power(dev, false);
982 if (ret)
983 dev_err(&pdev->dev, "Failed to power down\n");
927 984
928 return 0; 985 return 0;
929} 986}
@@ -1025,7 +1082,9 @@ static int bcm_serdev_probe(struct serdev_device *serdev)
1025 if (err) 1082 if (err)
1026 return err; 1083 return err;
1027 1084
1028 bcm_gpio_set_power(bcmdev, false); 1085 err = bcm_gpio_set_power(bcmdev, false);
1086 if (err)
1087 dev_err(&serdev->dev, "Failed to power down\n");
1029 1088
1030 return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto); 1089 return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
1031} 1090}