diff options
Diffstat (limited to 'drivers/bluetooth')
| -rw-r--r-- | drivers/bluetooth/btintel_pcie.c | 3 | ||||
| -rw-r--r-- | drivers/bluetooth/btmtksdio.c | 8 | ||||
| -rw-r--r-- | drivers/bluetooth/btnxpuart.c | 6 | ||||
| -rw-r--r-- | drivers/bluetooth/btqca.c | 58 | ||||
| -rw-r--r-- | drivers/bluetooth/btusb.c | 26 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_bcm4377.c | 11 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_intel.c | 10 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_qca.c | 52 |
8 files changed, 109 insertions, 65 deletions
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c index 704767b334b9..eaf5de46a702 100644 --- a/drivers/bluetooth/btintel_pcie.c +++ b/drivers/bluetooth/btintel_pcie.c @@ -1190,8 +1190,7 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data, skb = NULL; /* skb is freed in the callee */ exit_error: - if (skb) - kfree_skb(skb); + kfree_skb(skb); if (ret) hdev->stat.err_rx++; diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index fba3ab6d30a5..e986e5af51ae 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -1472,7 +1472,6 @@ static void btmtksdio_remove(struct sdio_func *func) hci_free_dev(hdev); } -#ifdef CONFIG_PM static int btmtksdio_runtime_suspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); @@ -1542,18 +1541,13 @@ static const struct dev_pm_ops btmtksdio_pm_ops = { RUNTIME_PM_OPS(btmtksdio_runtime_suspend, btmtksdio_runtime_resume, NULL) }; -#define BTMTKSDIO_PM_OPS (&btmtksdio_pm_ops) -#else /* CONFIG_PM */ -#define BTMTKSDIO_PM_OPS NULL -#endif /* CONFIG_PM */ - static struct sdio_driver btmtksdio_driver = { .name = "btmtksdio", .probe = btmtksdio_probe, .remove = btmtksdio_remove, .id_table = btmtksdio_table, .drv = { - .pm = BTMTKSDIO_PM_OPS, + .pm = pm_ptr(&btmtksdio_pm_ops), } }; diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c index 3b1e9224e965..e7036a48ce48 100644 --- a/drivers/bluetooth/btnxpuart.c +++ b/drivers/bluetooth/btnxpuart.c @@ -1947,8 +1947,7 @@ static void nxp_serdev_remove(struct serdev_device *serdev) hci_free_dev(hdev); } -#ifdef CONFIG_PM_SLEEP -static int nxp_serdev_suspend(struct device *dev) +static int __maybe_unused nxp_serdev_suspend(struct device *dev) { struct btnxpuart_dev *nxpdev = dev_get_drvdata(dev); struct ps_data *psdata = &nxpdev->psdata; @@ -1962,7 +1961,7 @@ static int nxp_serdev_suspend(struct device *dev) return 0; } -static int nxp_serdev_resume(struct device *dev) +static int __maybe_unused nxp_serdev_resume(struct device *dev) { struct btnxpuart_dev *nxpdev = dev_get_drvdata(dev); struct ps_data *psdata = &nxpdev->psdata; @@ -1975,7 +1974,6 @@ static int nxp_serdev_resume(struct device *dev) ps_control(psdata->hdev, PS_STATE_AWAKE); return 0; } -#endif #ifdef CONFIG_DEV_COREDUMP static void nxp_serdev_coredump(struct device *dev) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 7c958d6065be..74f820e89655 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -581,28 +581,11 @@ static int qca_download_firmware(struct hci_dev *hdev, ret = request_firmware(&fw, config->fwname, &hdev->dev); if (ret) { - /* For WCN6750, if mbn file is not present then check for - * tlv file. - */ - if (soc_type == QCA_WCN6750 && config->type == ELF_TYPE_PATCH) { - bt_dev_dbg(hdev, "QCA Failed to request file: %s (%d)", - config->fwname, ret); - config->type = TLV_TYPE_PATCH; - snprintf(config->fwname, sizeof(config->fwname), - "qca/msbtfw%02x.tlv", rom_ver); - bt_dev_info(hdev, "QCA Downloading %s", config->fwname); - ret = request_firmware(&fw, config->fwname, &hdev->dev); - if (ret) { - bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", - config->fwname, ret); - return ret; - } - } /* If the board-specific file is missing, try loading the default * one, unless that was attempted already. */ - else if (config->type == TLV_TYPE_NVM && - qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) { + if (config->type == TLV_TYPE_NVM && + qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) { bt_dev_info(hdev, "QCA Downloading %s", config->fwname); ret = request_firmware(&fw, config->fwname, &hdev->dev); if (ret) { @@ -847,8 +830,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, "qca/msbtfw%02x.mbn", rom_ver); break; case QCA_WCN6855: + /* Due to historical reasons, WCN685x chip has been using firmware + * without the "wcn" prefix. The mapping between the chip and its + * corresponding firmware has now been corrected. + */ snprintf(config.fwname, sizeof(config.fwname), - "qca/hpbtfw%02x.tlv", rom_ver); + "qca/wcnhpbtfw%02x.tlv", rom_ver); break; case QCA_WCN7850: snprintf(config.fwname, sizeof(config.fwname), @@ -861,8 +848,26 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, } err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + /* For WCN6750, if mbn file is not present then check for + * tlv file. + */ + if (err < 0 && soc_type == QCA_WCN6750) { + bt_dev_dbg(hdev, "QCA Failed to request file: %s (%d)", + config.fwname, err); + config.type = TLV_TYPE_PATCH; + snprintf(config.fwname, sizeof(config.fwname), + "qca/msbtfw%02x.tlv", rom_ver); + bt_dev_info(hdev, "QCA Downloading %s", config.fwname); + err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + } else if (err < 0 && !rampatch_name && soc_type == QCA_WCN6855) { + snprintf(config.fwname, sizeof(config.fwname), + "qca/hpbtfw%02x.tlv", rom_ver); + err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + } + if (err < 0) { - bt_dev_err(hdev, "QCA Failed to download patch (%d)", err); + bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", + config.fwname, err); return err; } @@ -923,7 +928,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, case QCA_WCN6855: qca_read_fw_board_id(hdev, &boardid); qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname), - "hpnv", soc_type, ver, rom_ver, boardid); + "wcnhpnv", soc_type, ver, rom_ver, boardid); break; case QCA_WCN7850: qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname), @@ -936,8 +941,15 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, } err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + if (err < 0 && !firmware_name && soc_type == QCA_WCN6855) { + qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname), + "hpnv", soc_type, ver, rom_ver, boardid); + err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + } + if (err < 0) { - bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err); + bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", + config.fwname, err); return err; } diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ded09e94d296..fcec8e589e81 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -521,12 +521,16 @@ static const struct usb_device_id quirks_table[] = { { USB_DEVICE(0x0bda, 0xb850), .driver_info = BTUSB_REALTEK }, { USB_DEVICE(0x13d3, 0x3600), .driver_info = BTUSB_REALTEK }, { USB_DEVICE(0x13d3, 0x3601), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x0489, 0xe112), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Realtek 8851BU Bluetooth devices */ { USB_DEVICE(0x3625, 0x010b), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x2001, 0x332a), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x7392, 0xe611), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Realtek 8852AE Bluetooth devices */ { USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK | @@ -557,6 +561,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3592), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3612), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0489, 0xe122), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, @@ -577,8 +583,6 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3591), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, - { USB_DEVICE(0x13d3, 0x3618), .driver_info = BTUSB_REALTEK | - BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0489, 0xe123), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0489, 0xe125), .driver_info = BTUSB_REALTEK | @@ -637,6 +641,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3622), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe158), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, /* Additional MediaTek MT7921 Bluetooth devices */ { USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK | @@ -773,6 +779,7 @@ static const struct usb_device_id quirks_table[] = { /* Additional Realtek 8723BU Bluetooth devices */ { USB_DEVICE(0x7392, 0xa611), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x2c0a, 0x8761), .driver_info = BTUSB_REALTEK }, /* Additional Realtek 8723DE Bluetooth devices */ { USB_DEVICE(0x0bda, 0xb009), .driver_info = BTUSB_REALTEK }, @@ -4462,17 +4469,17 @@ static void btusb_disconnect(struct usb_interface *intf) kfree(data); } -#ifdef CONFIG_PM static int btusb_suspend(struct usb_interface *intf, pm_message_t message) { struct btusb_data *data = usb_get_intfdata(intf); BT_DBG("intf %p", intf); - /* Don't auto-suspend if there are connections; external suspend calls - * shall never fail. + /* Don't auto-suspend if there are connections or discovery in + * progress; external suspend calls shall never fail. */ - if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev)) + if (PMSG_IS_AUTO(message) && + (hci_conn_count(data->hdev) || hci_discovery_active(data->hdev))) return -EBUSY; if (data->suspend_count++) @@ -4616,7 +4623,6 @@ done: return err; } -#endif #ifdef CONFIG_DEV_COREDUMP static void btusb_coredump(struct device *dev) @@ -4633,10 +4639,8 @@ static struct usb_driver btusb_driver = { .name = "btusb", .probe = btusb_probe, .disconnect = btusb_disconnect, -#ifdef CONFIG_PM - .suspend = btusb_suspend, - .resume = btusb_resume, -#endif + .suspend = pm_ptr(btusb_suspend), + .resume = pm_ptr(btusb_resume), .id_table = btusb_table, .supports_autosuspend = 1, .disable_hub_initiated_lpm = 1, diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c index 45e6d84224ee..925d0a635945 100644 --- a/drivers/bluetooth/hci_bcm4377.c +++ b/drivers/bluetooth/hci_bcm4377.c @@ -2416,8 +2416,9 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id) hdev); } -static int bcm4377_suspend(struct pci_dev *pdev, pm_message_t state) +static int bcm4377_suspend(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct bcm4377_data *bcm4377 = pci_get_drvdata(pdev); int ret; @@ -2431,8 +2432,9 @@ static int bcm4377_suspend(struct pci_dev *pdev, pm_message_t state) return 0; } -static int bcm4377_resume(struct pci_dev *pdev) +static int bcm4377_resume(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct bcm4377_data *bcm4377 = pci_get_drvdata(pdev); iowrite32(BCM4377_BAR0_SLEEP_CONTROL_UNQUIESCE, @@ -2441,6 +2443,8 @@ static int bcm4377_resume(struct pci_dev *pdev) return hci_resume_dev(bcm4377->hdev); } +static DEFINE_SIMPLE_DEV_PM_OPS(bcm4377_ops, bcm4377_suspend, bcm4377_resume); + static const struct dmi_system_id bcm4377_dmi_board_table[] = { { .matches = { @@ -2541,8 +2545,7 @@ static struct pci_driver bcm4377_pci_driver = { .name = "hci_bcm4377", .id_table = bcm4377_devid_table, .probe = bcm4377_probe, - .suspend = bcm4377_suspend, - .resume = bcm4377_resume, + .driver.pm = &bcm4377_ops, }; module_pci_driver(bcm4377_pci_driver); diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index 20baf2895dec..f7570c2eaa46 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -126,7 +126,6 @@ static int intel_wait_booting(struct hci_uart *hu) return err; } -#ifdef CONFIG_PM static int intel_wait_lpm_transaction(struct hci_uart *hu) { struct intel_data *intel = hu->priv; @@ -237,7 +236,6 @@ static int intel_lpm_resume(struct hci_uart *hu) return 0; } -#endif /* CONFIG_PM */ static int intel_lpm_host_wake(struct hci_uart *hu) { @@ -1066,7 +1064,6 @@ static const struct acpi_device_id intel_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, intel_acpi_match); #endif -#ifdef CONFIG_PM static int intel_suspend_device(struct device *dev) { struct intel_device *idev = dev_get_drvdata(dev); @@ -1090,10 +1087,8 @@ static int intel_resume_device(struct device *dev) return 0; } -#endif -#ifdef CONFIG_PM_SLEEP -static int intel_suspend(struct device *dev) +static int __maybe_unused intel_suspend(struct device *dev) { struct intel_device *idev = dev_get_drvdata(dev); @@ -1103,7 +1098,7 @@ static int intel_suspend(struct device *dev) return intel_suspend_device(dev); } -static int intel_resume(struct device *dev) +static int __maybe_unused intel_resume(struct device *dev) { struct intel_device *idev = dev_get_drvdata(dev); @@ -1112,7 +1107,6 @@ static int intel_resume(struct device *dev) return intel_resume_device(dev); } -#endif static const struct dev_pm_ops intel_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 888176b0faa9..51309f5b5714 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -87,6 +87,7 @@ enum qca_flags { enum qca_capabilities { QCA_CAP_WIDEBAND_SPEECH = BIT(0), QCA_CAP_VALID_LE_STATES = BIT(1), + QCA_CAP_HFP_HW_OFFLOAD = BIT(2), }; /* HCI_IBS transmit side sleep protocol states */ @@ -229,6 +230,7 @@ struct qca_serdev { u32 init_speed; u32 oper_speed; bool bdaddr_property_broken; + bool support_hfp_hw_offload; const char *firmware_name[2]; }; @@ -1653,6 +1655,39 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code) skb_queue_purge(&qca->rx_memdump_q); } + /* + * If the BT chip's bt_en pin is connected to a 3.3V power supply via + * hardware and always stays high, driver cannot control the bt_en pin. + * As a result, during SSR (SubSystem Restart), QCA_SSR_TRIGGERED and + * QCA_IBS_DISABLED flags cannot be cleared, which leads to a reset + * command timeout. + * Add an msleep delay to ensure controller completes the SSR process. + * + * Host will not download the firmware after SSR, controller to remain + * in the IBS_WAKE state, and the host needs to synchronize with it + * + * Since the bluetooth chip has been reset, clear the memdump state. + */ + if (!hci_test_quirk(hu->hdev, HCI_QUIRK_NON_PERSISTENT_SETUP)) { + /* + * When the SSR (SubSystem Restart) duration exceeds 2 seconds, + * it triggers host tx_idle_delay, which sets host TX state + * to sleep. Reset tx_idle_timer after SSR to prevent + * host enter TX IBS_Sleep mode. + */ + mod_timer(&qca->tx_idle_timer, jiffies + + msecs_to_jiffies(qca->tx_idle_delay)); + + /* Controller reset completion time is 50ms */ + msleep(50); + + clear_bit(QCA_SSR_TRIGGERED, &qca->flags); + clear_bit(QCA_IBS_DISABLED, &qca->flags); + + qca->tx_ibs_state = HCI_IBS_TX_AWAKE; + qca->memdump_state = QCA_MEMDUMP_IDLE; + } + clear_bit(QCA_HW_ERROR_EVENT, &qca->flags); } @@ -1879,7 +1914,7 @@ static int qca_setup(struct hci_uart *hu) const char *rampatch_name = qca_get_rampatch_name(hu); int ret; struct qca_btsoc_version ver; - struct qca_serdev *qcadev; + struct qca_serdev *qcadev = serdev_device_get_drvdata(hu->serdev); const char *soc_name; ret = qca_check_speeds(hu); @@ -1943,7 +1978,6 @@ retry: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: - qcadev = serdev_device_get_drvdata(hu->serdev); if (qcadev->bdaddr_property_broken) hci_set_quirk(hdev, HCI_QUIRK_BDADDR_PROPERTY_BROKEN); @@ -2033,7 +2067,7 @@ out: else hu->hdev->set_bdaddr = qca_set_bdaddr; - if (soc_type == QCA_QCA2066) + if (qcadev->support_hfp_hw_offload) qca_configure_hfp_offload(hdev); qca->fw_version = le16_to_cpu(ver.patch_ver); @@ -2117,7 +2151,8 @@ static const struct qca_device_data qca_soc_data_wcn3998 __maybe_unused = { static const struct qca_device_data qca_soc_data_qca2066 __maybe_unused = { .soc_type = QCA_QCA2066, .num_vregs = 0, - .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, + .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES | + QCA_CAP_HFP_HW_OFFLOAD, }; static const struct qca_device_data qca_soc_data_qca6390 __maybe_unused = { @@ -2153,7 +2188,8 @@ static const struct qca_device_data qca_soc_data_wcn6855 __maybe_unused = { { "vddrfa1p2", 257000 }, }, .num_vregs = 6, - .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, + .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES | + QCA_CAP_HFP_HW_OFFLOAD, }; static const struct qca_device_data qca_soc_data_wcn7850 __maybe_unused = { @@ -2167,7 +2203,8 @@ static const struct qca_device_data qca_soc_data_wcn7850 __maybe_unused = { { "vddrfa1p9", 302000 }, }, .num_vregs = 6, - .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, + .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES | + QCA_CAP_HFP_HW_OFFLOAD, }; static void qca_power_shutdown(struct hci_uart *hu) @@ -2502,6 +2539,9 @@ static int qca_serdev_probe(struct serdev_device *serdev) if (!(data->capabilities & QCA_CAP_VALID_LE_STATES)) hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LE_STATES); + + if (data->capabilities & QCA_CAP_HFP_HW_OFFLOAD) + qcadev->support_hfp_hw_offload = true; } return 0; |
