Merge tag 'io_uring-5.13-2021-05-07' of git://git.kernel.dk/linux-block
[linux-block.git] / drivers / bluetooth / hci_bcm.c
index 3764ceb6fa0d52a454bd2954f8c19c4e10ba060a..3cd57fc56adea1f2d74213239562a207938b97e7 100644 (file)
@@ -68,6 +68,8 @@ struct bcm_device_data {
  *     deassert = Bluetooth device may sleep when sleep criteria are met
  * @shutdown: BT_REG_ON pin,
  *     power up or power down Bluetooth device internal regulators
+ * @reset: BT_RST_N pin,
+ *     active low resets the Bluetooth logic core
  * @set_device_wakeup: callback to toggle BT_WAKE pin
  *     either by accessing @device_wakeup or by calling @btlp
  * @set_shutdown: callback to toggle BT_REG_ON pin
@@ -101,6 +103,7 @@ struct bcm_device {
        const char              *name;
        struct gpio_desc        *device_wakeup;
        struct gpio_desc        *shutdown;
+       struct gpio_desc        *reset;
        int                     (*set_device_wakeup)(struct bcm_device *, bool);
        int                     (*set_shutdown)(struct bcm_device *, bool);
 #ifdef CONFIG_ACPI
@@ -985,6 +988,15 @@ static int bcm_gpio_set_device_wakeup(struct bcm_device *dev, bool awake)
 static int bcm_gpio_set_shutdown(struct bcm_device *dev, bool powered)
 {
        gpiod_set_value_cansleep(dev->shutdown, powered);
+       if (dev->reset)
+               /*
+                * The reset line is asserted on powerdown and deasserted
+                * on poweron so the inverse of powered is used. Notice
+                * that the GPIO line BT_RST_N needs to be specified as
+                * active low in the device tree or similar system
+                * description.
+                */
+               gpiod_set_value_cansleep(dev->reset, !powered);
        return 0;
 }
 
@@ -1050,6 +1062,11 @@ static int bcm_get_resources(struct bcm_device *dev)
        if (IS_ERR(dev->shutdown))
                return PTR_ERR(dev->shutdown);
 
+       dev->reset = devm_gpiod_get_optional(dev->dev, "reset",
+                                            GPIOD_OUT_LOW);
+       if (IS_ERR(dev->reset))
+               return PTR_ERR(dev->reset);
+
        dev->set_device_wakeup = bcm_gpio_set_device_wakeup;
        dev->set_shutdown = bcm_gpio_set_shutdown;
 
@@ -1482,6 +1499,8 @@ static struct bcm_device_data bcm43438_device_data = {
 static const struct of_device_id bcm_bluetooth_of_match[] = {
        { .compatible = "brcm,bcm20702a1" },
        { .compatible = "brcm,bcm4329-bt" },
+       { .compatible = "brcm,bcm4330-bt" },
+       { .compatible = "brcm,bcm4334-bt" },
        { .compatible = "brcm,bcm4345c5" },
        { .compatible = "brcm,bcm4330-bt" },
        { .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data },