diff options
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/bpa10x.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/btbcm.c | 3 | ||||
-rw-r--r-- | drivers/bluetooth/btqca.c | 30 | ||||
-rw-r--r-- | drivers/bluetooth/btqca.h | 7 | ||||
-rw-r--r-- | drivers/bluetooth/btrtl.c | 125 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 75 | ||||
-rw-r--r-- | drivers/bluetooth/hci_bcm.c | 33 | ||||
-rw-r--r-- | drivers/bluetooth/hci_qca.c | 47 |
8 files changed, 216 insertions, 106 deletions
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index a0e84538cec8..1fa58c059cbf 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c @@ -337,7 +337,7 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb) usb_free_urb(urb); - return 0; + return err; } static int bpa10x_set_diag(struct hci_dev *hdev, bool enable) diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 124ef0a3e1dd..2d2e6d862068 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -23,6 +23,7 @@ #define BDADDR_BCM43430A0 (&(bdaddr_t) {{0xac, 0x1f, 0x12, 0xa0, 0x43, 0x43}}) #define BDADDR_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}}) #define BDADDR_BCM4330B1 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb1, 0x30, 0x43}}) +#define BDADDR_BCM4345C5 (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0xc5, 0x45, 0x43}}) #define BDADDR_BCM43341B (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0x1b, 0x34, 0x43}}) int btbcm_check_bdaddr(struct hci_dev *hdev) @@ -73,6 +74,7 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) !bacmp(&bda->bdaddr, BDADDR_BCM2076B1) || !bacmp(&bda->bdaddr, BDADDR_BCM4324B3) || !bacmp(&bda->bdaddr, BDADDR_BCM4330B1) || + !bacmp(&bda->bdaddr, BDADDR_BCM4345C5) || !bacmp(&bda->bdaddr, BDADDR_BCM43430A0) || !bacmp(&bda->bdaddr, BDADDR_BCM43341B)) { bt_dev_info(hdev, "BCM: Using default device address (%pMR)", @@ -332,6 +334,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = { { 0x2122, "BCM4343A0" }, /* 001.001.034 */ { 0x2209, "BCM43430A1" }, /* 001.002.009 */ { 0x6119, "BCM4345C0" }, /* 003.001.025 */ + { 0x6606, "BCM4345C5" }, /* 003.006.006 */ { 0x230f, "BCM4356A2" }, /* 001.003.015 */ { 0x220e, "BCM20702A1" }, /* 001.002.014 */ { 0x4217, "BCM4329B1" }, /* 002.002.023 */ diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 8b33128dccee..8cc21ad7cf29 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -99,6 +99,28 @@ static int qca_send_reset(struct hci_dev *hdev) return 0; } +int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) +{ + struct sk_buff *skb; + int err; + + bt_dev_dbg(hdev, "QCA pre shutdown cmd"); + + skb = __hci_cmd_sync_ev(hdev, QCA_PRE_SHUTDOWN_CMD, 0, + NULL, HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT); + + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + bt_dev_err(hdev, "QCA preshutdown_cmd failed (%d)", err); + return err; + } + + kfree_skb(skb); + + return 0; +} +EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); + static void qca_tlv_check_data(struct rome_config *config, const struct firmware *fw) { @@ -119,6 +141,7 @@ static void qca_tlv_check_data(struct rome_config *config, BT_DBG("Length\t\t : %d bytes", length); config->dnld_mode = ROME_SKIP_EVT_NONE; + config->dnld_type = ROME_SKIP_EVT_NONE; switch (config->type) { case TLV_TYPE_PATCH: @@ -268,7 +291,7 @@ static int qca_inject_cmd_complete_event(struct hci_dev *hdev) evt = skb_put(skb, sizeof(*evt)); evt->ncmd = 1; - evt->opcode = QCA_HCI_CC_OPCODE; + evt->opcode = cpu_to_le16(QCA_HCI_CC_OPCODE); skb_put_u8(skb, QCA_HCI_CC_SUCCESS); @@ -323,7 +346,7 @@ static int qca_download_firmware(struct hci_dev *hdev, */ if (config->dnld_type == ROME_SKIP_EVT_VSE_CC || config->dnld_type == ROME_SKIP_EVT_VSE) - return qca_inject_cmd_complete_event(hdev); + ret = qca_inject_cmd_complete_event(hdev); out: release_firmware(fw); @@ -388,6 +411,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, return err; } + /* Give the controller some time to get ready to receive the NVM */ + msleep(10); + /* Download NVM configuration */ config.type = TLV_TYPE_NVM; if (firmware_name) diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index 6a291a7a5d96..69c5315a65fd 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -13,6 +13,7 @@ #define EDL_PATCH_TLV_REQ_CMD (0x1E) #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) #define MAX_SIZE_PER_TLV_SEGMENT (243) +#define QCA_PRE_SHUTDOWN_CMD (0xFC08) #define EDL_CMD_REQ_RES_EVT (0x00) #define EDL_PATCH_VER_RES_EVT (0x19) @@ -135,6 +136,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, const char *firmware_name); int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version); int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); +int qca_send_pre_shutdown_cmd(struct hci_dev *hdev); static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) { return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3998; @@ -167,4 +169,9 @@ static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) { return false; } + +static inline int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) +{ + return -EOPNOTSUPP; +} #endif diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index 4f75a9b61d09..bf3c02be6930 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -178,6 +178,27 @@ static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev, return &ic_id_table[i]; } +static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev) +{ + struct sk_buff *skb; + + skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + rtl_dev_err(hdev, "HCI_OP_READ_LOCAL_VERSION failed (%ld)", + PTR_ERR(skb)); + return skb; + } + + if (skb->len != sizeof(struct hci_rp_read_local_version)) { + rtl_dev_err(hdev, "HCI_OP_READ_LOCAL_VERSION event length mismatch"); + kfree_skb(skb); + return ERR_PTR(-EIO); + } + + return skb; +} + static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version) { struct rtl_rom_version_evt *rom_version; @@ -186,19 +207,19 @@ static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version) /* Read RTL ROM version command */ skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { - rtl_dev_err(hdev, "Read ROM version failed (%ld)\n", + rtl_dev_err(hdev, "Read ROM version failed (%ld)", PTR_ERR(skb)); return PTR_ERR(skb); } if (skb->len != sizeof(*rom_version)) { - rtl_dev_err(hdev, "RTL version event length mismatch\n"); + rtl_dev_err(hdev, "version event length mismatch"); kfree_skb(skb); return -EIO; } rom_version = (struct rtl_rom_version_evt *)skb->data; - rtl_dev_info(hdev, "rom_version status=%x version=%x\n", + rtl_dev_info(hdev, "rom_version status=%x version=%x", rom_version->status, rom_version->version); *version = rom_version->version; @@ -242,7 +263,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, fwptr = btrtl_dev->fw_data + btrtl_dev->fw_len - sizeof(extension_sig); if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) { - rtl_dev_err(hdev, "extension section signature mismatch\n"); + rtl_dev_err(hdev, "extension section signature mismatch"); return -EINVAL; } @@ -263,7 +284,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, break; if (length == 0) { - rtl_dev_err(hdev, "found instruction with length 0\n"); + rtl_dev_err(hdev, "found instruction with length 0"); return -EINVAL; } @@ -276,7 +297,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, } if (project_id < 0) { - rtl_dev_err(hdev, "failed to find version instruction\n"); + rtl_dev_err(hdev, "failed to find version instruction"); return -EINVAL; } @@ -287,13 +308,13 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, } if (i >= ARRAY_SIZE(project_id_to_lmp_subver)) { - rtl_dev_err(hdev, "unknown project id %d\n", project_id); + rtl_dev_err(hdev, "unknown project id %d", project_id); return -EINVAL; } if (btrtl_dev->ic_info->lmp_subver != project_id_to_lmp_subver[i].lmp_subver) { - rtl_dev_err(hdev, "firmware is for %x but this is a %x\n", + rtl_dev_err(hdev, "firmware is for %x but this is a %x", project_id_to_lmp_subver[i].lmp_subver, btrtl_dev->ic_info->lmp_subver); return -EINVAL; @@ -301,7 +322,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, epatch_info = (struct rtl_epatch_header *)btrtl_dev->fw_data; if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) { - rtl_dev_err(hdev, "bad EPATCH signature\n"); + rtl_dev_err(hdev, "bad EPATCH signature"); return -EINVAL; } @@ -368,6 +389,8 @@ static int rtl_download_firmware(struct hci_dev *hdev, int frag_len = RTL_FRAG_LEN; int ret = 0; int i; + struct sk_buff *skb; + struct hci_rp_read_local_version *rp; dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL); if (!dl_cmd) @@ -378,7 +401,11 @@ static int rtl_download_firmware(struct hci_dev *hdev, BT_DBG("download fw (%d/%d)", i, frag_num); - dl_cmd->index = i; + if (i > 0x7f) + dl_cmd->index = (i & 0x7f) + 1; + else + dl_cmd->index = i; + if (i == (frag_num - 1)) { dl_cmd->index |= 0x80; /* data end */ frag_len = fw_len % RTL_FRAG_LEN; @@ -389,14 +416,14 @@ static int rtl_download_firmware(struct hci_dev *hdev, skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { - rtl_dev_err(hdev, "download fw command failed (%ld)\n", + rtl_dev_err(hdev, "download fw command failed (%ld)", PTR_ERR(skb)); ret = -PTR_ERR(skb); goto out; } if (skb->len != sizeof(struct rtl_download_response)) { - rtl_dev_err(hdev, "download fw event length mismatch\n"); + rtl_dev_err(hdev, "download fw event length mismatch"); kfree_skb(skb); ret = -EIO; goto out; @@ -406,6 +433,18 @@ static int rtl_download_firmware(struct hci_dev *hdev, data += RTL_FRAG_LEN; } + skb = btrtl_read_local_version(hdev); + if (IS_ERR(skb)) { + ret = PTR_ERR(skb); + rtl_dev_err(hdev, "read local version failed"); + goto out; + } + + rp = (struct hci_rp_read_local_version *)skb->data; + rtl_dev_info(hdev, "fw version 0x%04x%04x", + __le16_to_cpu(rp->hci_rev), __le16_to_cpu(rp->lmp_subver)); + kfree_skb(skb); + out: kfree(dl_cmd); return ret; @@ -416,7 +455,7 @@ static int rtl_load_file(struct hci_dev *hdev, const char *name, u8 **buff) const struct firmware *fw; int ret; - rtl_dev_info(hdev, "rtl: loading %s\n", name); + rtl_dev_info(hdev, "loading %s", name); ret = request_firmware(&fw, name, &hdev->dev); if (ret < 0) return ret; @@ -440,7 +479,7 @@ static int btrtl_setup_rtl8723a(struct hci_dev *hdev, * (which is only for RTL8723B and newer). */ if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8)) { - rtl_dev_err(hdev, "unexpected EPATCH signature!\n"); + rtl_dev_err(hdev, "unexpected EPATCH signature!"); return -EINVAL; } @@ -475,7 +514,7 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev, fw_data = tbuff; } - rtl_dev_info(hdev, "cfg_sz %d, total sz %d\n", btrtl_dev->cfg_len, ret); + rtl_dev_info(hdev, "cfg_sz %d, total sz %d", btrtl_dev->cfg_len, ret); ret = rtl_download_firmware(hdev, fw_data, ret); @@ -484,27 +523,6 @@ out: return ret; } -static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev) -{ - struct sk_buff *skb; - - skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, - HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - rtl_dev_err(hdev, "HCI_OP_READ_LOCAL_VERSION failed (%ld)\n", - PTR_ERR(skb)); - return skb; - } - - if (skb->len != sizeof(struct hci_rp_read_local_version)) { - rtl_dev_err(hdev, "HCI_OP_READ_LOCAL_VERSION event length mismatch\n"); - kfree_skb(skb); - return ERR_PTR(-EIO); - } - - return skb; -} - void btrtl_free(struct btrtl_device_info *btrtl_dev) { kfree(btrtl_dev->fw_data); @@ -537,7 +555,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, } resp = (struct hci_rp_read_local_version *)skb->data; - rtl_dev_info(hdev, "rtl: examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x lmp_subver=%04x\n", + rtl_dev_info(hdev, "examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x lmp_subver=%04x", resp->hci_ver, resp->hci_rev, resp->lmp_ver, resp->lmp_subver); @@ -550,7 +568,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, hdev->bus); if (!btrtl_dev->ic_info) { - rtl_dev_info(hdev, "rtl: unknown IC info, lmp subver %04x, hci rev %04x, hci ver %04x", + rtl_dev_info(hdev, "unknown IC info, lmp subver %04x, hci rev %04x, hci ver %04x", lmp_subver, hci_rev, hci_ver); return btrtl_dev; } @@ -564,7 +582,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, btrtl_dev->fw_len = rtl_load_file(hdev, btrtl_dev->ic_info->fw_name, &btrtl_dev->fw_data); if (btrtl_dev->fw_len < 0) { - rtl_dev_err(hdev, "firmware file %s not found\n", + rtl_dev_err(hdev, "firmware file %s not found", btrtl_dev->ic_info->fw_name); ret = btrtl_dev->fw_len; goto err_free; @@ -582,7 +600,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, &btrtl_dev->cfg_data); if (btrtl_dev->ic_info->config_needed && btrtl_dev->cfg_len <= 0) { - rtl_dev_err(hdev, "mandatory config file %s not found\n", + rtl_dev_err(hdev, "mandatory config file %s not found", btrtl_dev->ic_info->cfg_name); ret = btrtl_dev->cfg_len; goto err_free; @@ -608,7 +626,7 @@ int btrtl_download_firmware(struct hci_dev *hdev, * to a different value. */ if (!btrtl_dev->ic_info) { - rtl_dev_info(hdev, "rtl: assuming no firmware upload needed\n"); + rtl_dev_info(hdev, "assuming no firmware upload needed"); return 0; } @@ -622,7 +640,7 @@ int btrtl_download_firmware(struct hci_dev *hdev, case RTL_ROM_LMP_8822B: return btrtl_setup_rtl8723b(hdev, btrtl_dev); default: - rtl_dev_info(hdev, "rtl: assuming no firmware upload needed\n"); + rtl_dev_info(hdev, "assuming no firmware upload needed"); return 0; } } @@ -641,6 +659,11 @@ int btrtl_setup_realtek(struct hci_dev *hdev) btrtl_free(btrtl_dev); + /* Enable controller to do both LE scan and BR/EDR inquiry + * simultaneously. + */ + set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); + return ret; } EXPORT_SYMBOL_GPL(btrtl_setup_realtek); @@ -714,18 +737,18 @@ int btrtl_get_uart_settings(struct hci_dev *hdev, total_data_len = btrtl_dev->cfg_len - sizeof(*config); if (total_data_len <= 0) { - rtl_dev_warn(hdev, "no config loaded\n"); + rtl_dev_warn(hdev, "no config loaded"); return -EINVAL; } config = (struct rtl_vendor_config *)btrtl_dev->cfg_data; if (le32_to_cpu(config->signature) != RTL_CONFIG_MAGIC) { - rtl_dev_err(hdev, "invalid config magic\n"); + rtl_dev_err(hdev, "invalid config magic"); return -EINVAL; } if (total_data_len < le16_to_cpu(config->total_len)) { - rtl_dev_err(hdev, "config is too short\n"); + rtl_dev_err(hdev, "config is too short"); return -EINVAL; } @@ -735,7 +758,7 @@ int btrtl_get_uart_settings(struct hci_dev *hdev, switch (le16_to_cpu(entry->offset)) { case 0xc: if (entry->len < sizeof(*device_baudrate)) { - rtl_dev_err(hdev, "invalid UART config entry\n"); + rtl_dev_err(hdev, "invalid UART config entry"); return -EINVAL; } @@ -752,7 +775,7 @@ int btrtl_get_uart_settings(struct hci_dev *hdev, break; default: - rtl_dev_dbg(hdev, "skipping config entry 0x%x (len %u)\n", + rtl_dev_dbg(hdev, "skipping config entry 0x%x (len %u)", le16_to_cpu(entry->offset), entry->len); break; }; @@ -761,13 +784,13 @@ int btrtl_get_uart_settings(struct hci_dev *hdev, } if (!found) { - rtl_dev_err(hdev, "no UART config entry found\n"); + rtl_dev_err(hdev, "no UART config entry found"); return -ENOENT; } - rtl_dev_dbg(hdev, "device baudrate = 0x%08x\n", *device_baudrate); - rtl_dev_dbg(hdev, "controller baudrate = %u\n", *controller_baudrate); - rtl_dev_dbg(hdev, "flow control %d\n", *flow_control); + rtl_dev_dbg(hdev, "device baudrate = 0x%08x", *device_baudrate); + rtl_dev_dbg(hdev, "controller baudrate = %u", *controller_baudrate); + rtl_dev_dbg(hdev, "flow control %d", *flow_control); return 0; } diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 3876fee6ad13..a9c35ebb30f8 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -384,6 +384,9 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3526), .driver_info = BTUSB_REALTEK }, { USB_DEVICE(0x0b05, 0x185c), .driver_info = BTUSB_REALTEK }, + /* Additional Realtek 8822CE Bluetooth devices */ + { USB_DEVICE(0x04ca, 0x4005), .driver_info = BTUSB_REALTEK }, + /* Silicon Wave based devices */ { USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE }, @@ -435,6 +438,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = { #define BTUSB_OOB_WAKE_ENABLED 11 #define BTUSB_HW_RESET_ACTIVE 12 #define BTUSB_TX_WAIT_VND_EVT 13 +#define BTUSB_WAKEUP_DISABLE 14 struct btusb_data { struct hci_dev *hdev; @@ -523,6 +527,36 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev) gpiod_set_value_cansleep(reset_gpio, 0); } +static void btusb_rtl_cmd_timeout(struct hci_dev *hdev) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + struct gpio_desc *reset_gpio = data->reset_gpio; + + if (++data->cmd_timeout_cnt < 5) + return; + + if (!reset_gpio) { + bt_dev_err(hdev, "No gpio to reset Realtek device, ignoring"); + return; + } + + /* Toggle the hard reset line. The Realtek device is going to + * yank itself off the USB and then replug. The cleanup is handled + * correctly on the way out (standard USB disconnect), and the new + * device is detected cleanly and bound to the driver again like + * it should be. + */ + if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) { + bt_dev_err(hdev, "last reset failed? Not resetting again"); + return; + } + + bt_dev_err(hdev, "Reset Realtek device via gpio"); + gpiod_set_value_cansleep(reset_gpio, 0); + msleep(200); + gpiod_set_value_cansleep(reset_gpio, 1); +} + static inline void btusb_free_frags(struct btusb_data *data) { unsigned long flags; @@ -1170,10 +1204,13 @@ static int btusb_open(struct hci_dev *hdev) } data->intf->needs_remote_wakeup = 1; - /* device specific wakeup source enabled and required for USB - * remote wakeup while host is suspended + + /* Disable device remote wakeup when host is suspended + * For Realtek chips, global suspend without + * SET_FEATURE (DEVICE_REMOTE_WAKEUP) can save more power in device. */ - device_wakeup_enable(&data->udev->dev); + if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags)) + device_wakeup_disable(&data->udev->dev); if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags)) goto done; @@ -1238,7 +1275,11 @@ static int btusb_close(struct hci_dev *hdev) goto failed; data->intf->needs_remote_wakeup = 0; - device_wakeup_disable(&data->udev->dev); + + /* Enable remote wake up for auto-suspend */ + if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags)) + data->intf->needs_remote_wakeup = 1; + usb_autopm_put_interface(data->intf); failed: @@ -2762,8 +2803,10 @@ static int btusb_mtk_setup_firmware(struct hci_dev *hdev, const char *fwname) fw_size = fw->size; /* The size of patch header is 30 bytes, should be skip */ - if (fw_size < 30) + if (fw_size < 30) { + err = -EINVAL; goto err_release_fw; + } fw_size -= 30; fw_ptr += 30; @@ -3768,12 +3811,13 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_REALTEK) { hdev->setup = btrtl_setup_realtek; hdev->shutdown = btrtl_shutdown_realtek; + hdev->cmd_timeout = btusb_rtl_cmd_timeout; - /* Realtek devices lose their updated firmware over suspend, - * but the USB hub doesn't notice any status change. - * Explicitly request a device reset on resume. + /* Realtek devices lose their updated firmware over global + * suspend that means host doesn't send SET_FEATURE + * (DEVICE_REMOTE_WAKEUP) */ - interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME; + set_bit(BTUSB_WAKEUP_DISABLE, &data->flags); } #endif @@ -3947,6 +3991,19 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) enable_irq(data->oob_wake_irq); } + /* For global suspend, Realtek devices lose the loaded fw + * in them. But for autosuspend, firmware should remain. + * Actually, it depends on whether the usb host sends + * set feature (enable wakeup) or not. + */ + if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags)) { + if (PMSG_IS_AUTO(message) && + device_can_wakeup(&data->udev->dev)) + data->udev->do_remote_wakeup = 1; + else if (!PMSG_IS_AUTO(message)) + data->udev->reset_resume = 1; + } + return 0; } diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index ae2624fce913..7646636f2d18 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -260,7 +260,7 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) } /* wait for device to power on and come out of reset */ - usleep_range(10000, 20000); + usleep_range(100000, 120000); dev->res_enabled = powered; @@ -824,6 +824,21 @@ unlock: } #endif +/* Some firmware reports an IRQ which does not work (wrong pin in fw table?) */ +static const struct dmi_system_id bcm_broken_irq_dmi_table[] = { + { + .ident = "Meegopad T08", + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, + "To be filled by OEM."), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "T3 MRD"), + DMI_EXACT_MATCH(DMI_BOARD_VERSION, "V1.1"), + }, + }, + { } +}; + +#ifdef CONFIG_ACPI static const struct acpi_gpio_params first_gpio = { 0, 0, false }; static const struct acpi_gpio_params second_gpio = { 1, 0, false }; static const struct acpi_gpio_params third_gpio = { 2, 0, false }; @@ -842,21 +857,6 @@ static const struct acpi_gpio_mapping acpi_bcm_int_first_gpios[] = { { }, }; -/* Some firmware reports an IRQ which does not work (wrong pin in fw table?) */ -static const struct dmi_system_id bcm_broken_irq_dmi_table[] = { - { - .ident = "Meegopad T08", - .matches = { - DMI_EXACT_MATCH(DMI_BOARD_VENDOR, - "To be filled by OEM."), - DMI_EXACT_MATCH(DMI_BOARD_NAME, "T3 MRD"), - DMI_EXACT_MATCH(DMI_BOARD_VERSION, "V1.1"), - }, - }, - { } -}; - -#ifdef CONFIG_ACPI static int bcm_resource(struct acpi_resource *ares, void *data) { struct bcm_device *dev = data; @@ -1419,6 +1419,7 @@ static void bcm_serdev_remove(struct serdev_device *serdev) #ifdef CONFIG_OF static const struct of_device_id bcm_bluetooth_of_match[] = { { .compatible = "brcm,bcm20702a1" }, + { .compatible = "brcm,bcm4345c5" }, { .compatible = "brcm,bcm4330-bt" }, { .compatible = "brcm,bcm43438-bt" }, { }, diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 82a0a3691a63..e3164c200eac 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -309,13 +309,14 @@ static void qca_wq_awake_device(struct work_struct *work) ws_awake_device); struct hci_uart *hu = qca->hu; unsigned long retrans_delay; + unsigned long flags; BT_DBG("hu %p wq awake device", hu); /* Vote for serial clock */ serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu); - spin_lock(&qca->hci_ibs_lock); + spin_lock_irqsave(&qca->hci_ibs_lock, flags); /* Send wake indication to device */ if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0) @@ -327,7 +328,7 @@ static void qca_wq_awake_device(struct work_struct *work) retrans_delay = msecs_to_jiffies(qca->wake_retrans); mod_timer(&qca->wake_retrans_timer, jiffies + retrans_delay); - spin_unlock(&qca->hci_ibs_lock); + spin_unlock_irqrestore(&qca->hci_ibs_lock, flags); /* Actually send the packets */ hci_uart_tx_wakeup(hu); @@ -338,12 +339,13 @@ static void qca_wq_awake_rx(struct work_struct *work) struct qca_data *qca = container_of(work, struct qca_data, ws_awake_rx); struct hci_uart *hu = qca->hu; + unsigned long flags; BT_DBG("hu %p wq awake rx", hu); serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu); - spin_lock(&qca->hci_ibs_lock); + spin_lock_irqsave(&qca->hci_ibs_lock, flags); qca->rx_ibs_state = HCI_IBS_RX_AWAKE; /* Always acknowledge device wake up, @@ -354,7 +356,7 @@ static void qca_wq_awake_rx(struct work_struct *work) qca->ibs_sent_wacks++; - spin_unlock(&qca->hci_ibs_lock); + spin_unlock_irqrestore(&qca->hci_ibs_lock, flags); /* Actually send the packets */ hci_uart_tx_wakeup(hu); @@ -502,26 +504,7 @@ static int qca_open(struct hci_uart *hu) qca->tx_ibs_state = HCI_IBS_TX_ASLEEP; qca->rx_ibs_state = HCI_IBS_RX_ASLEEP; - /* clocks actually on, but we start votes off */ - qca->tx_vote = false; - qca->rx_vote = false; - qca->flags = 0; - - qca->ibs_sent_wacks = 0; - qca->ibs_sent_slps = 0; - qca->ibs_sent_wakes = 0; - qca->ibs_recv_wacks = 0; - qca->ibs_recv_slps = 0; - qca->ibs_recv_wakes = 0; qca->vote_last_jif = jiffies; - qca->vote_on_ms = 0; - qca->vote_off_ms = 0; - qca->votes_on = 0; - qca->votes_off = 0; - qca->tx_votes_on = 0; - qca->tx_votes_off = 0; - qca->rx_votes_on = 0; - qca->rx_votes_off = 0; hu->priv = qca; @@ -705,7 +688,7 @@ static void device_want_to_sleep(struct hci_uart *hu) unsigned long flags; struct qca_data *qca = hu->priv; - BT_DBG("hu %p want to sleep", hu); + BT_DBG("hu %p want to sleep in %d state", hu, qca->rx_ibs_state); spin_lock_irqsave(&qca->hci_ibs_lock, flags); @@ -720,7 +703,7 @@ static void device_want_to_sleep(struct hci_uart *hu) break; case HCI_IBS_RX_ASLEEP: - /* Fall through */ + break; default: /* Any other state is illegal */ @@ -912,7 +895,7 @@ static int qca_recv_event(struct hci_dev *hdev, struct sk_buff *skb) if (hdr->evt == HCI_EV_VENDOR) complete(&qca->drop_ev_comp); - kfree(skb); + kfree_skb(skb); return 0; } @@ -1261,6 +1244,11 @@ static int qca_setup(struct hci_uart *hu) /* Patch downloading has to be done without IBS mode */ clear_bit(QCA_IBS_ENABLED, &qca->flags); + /* Enable controller to do both LE scan and BR/EDR inquiry + * simultaneously. + */ + set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); + if (qca_is_wcn399x(soc_type)) { bt_dev_info(hdev, "setting up wcn3990"); @@ -1326,7 +1314,7 @@ static int qca_setup(struct hci_uart *hu) return ret; } -static struct hci_uart_proto qca_proto = { +static const struct hci_uart_proto qca_proto = { .id = HCI_UART_QCA, .name = "QCA", .manufacturer = 29, @@ -1386,6 +1374,11 @@ static int qca_power_off(struct hci_dev *hdev) { struct hci_uart *hu = hci_get_drvdata(hdev); + /* Perform pre shutdown command */ + qca_send_pre_shutdown_cmd(hdev); + + usleep_range(8000, 10000); + qca_power_shutdown(hu); return 0; } |