static int qca_power_setup(struct hci_uart *hu, bool on);
 static void qca_power_shutdown(struct hci_uart *hu);
+static int qca_power_off(struct hci_dev *hdev);
 
 static void __serial_clock_on(struct tty_struct *tty)
 {
 static int qca_wcn3990_init(struct hci_uart *hu)
 {
        struct hci_dev *hdev = hu->hdev;
+       struct qca_serdev *qcadev;
        int ret;
 
+       /* Check for vregs status, may be hci down has turned
+        * off the voltage regulator.
+        */
+       qcadev = serdev_device_get_drvdata(hu->serdev);
+       if (!qcadev->bt_power->vregs_on) {
+               serdev_device_close(hu->serdev);
+               ret = qca_power_setup(hu, true);
+               if (ret)
+                       return ret;
+
+               ret = serdev_device_open(hu->serdev);
+               if (ret) {
+                       bt_dev_err(hu->hdev, "failed to open port");
+                       return ret;
+               }
+       }
+
        /* Forcefully enable wcn3990 to enter in to boot mode. */
        host_set_baudrate(hu, 2400);
        ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
 
        if (qcadev->btsoc_type == QCA_WCN3990) {
                bt_dev_info(hdev, "setting up wcn3990");
+
+               /* Enable NON_PERSISTENT_SETUP QUIRK to ensure to execute
+                * setup for every hci up.
+                */
+               set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
+               hu->hdev->shutdown = qca_power_off;
                ret = qca_wcn3990_init(hu);
                if (ret)
                        return ret;
        qca_power_setup(hu, false);
 }
 
+static int qca_power_off(struct hci_dev *hdev)
+{
+       struct hci_uart *hu = hci_get_drvdata(hdev);
+
+       qca_power_shutdown(hu);
+       return 0;
+}
+
 static int qca_enable_regulator(struct qca_vreg vregs,
                                struct regulator *regulator)
 {