Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says: ==================== pull request: bluetooth-next 2019-09-06 Here's the main bluetooth-next pull request for the 5.4 kernel. - Cleanups & fixes to btrtl driver - Fixes for Realtek devices in btusb, e.g. for suspend handling - Firmware loading support for BCM4345C5 - hidp_send_message() return value handling fixes - Added support for utilizing Fast Advertising Interval - Various other minor cleanups & fixes Please let me know if there are any issues pulling. Thanks. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
fcd8c62709
|
@ -13,6 +13,7 @@ Required properties:
|
|||
* "brcm,bcm20702a1"
|
||||
* "brcm,bcm4330-bt"
|
||||
* "brcm,bcm43438-bt"
|
||||
* "brcm,bcm4345c5"
|
||||
|
||||
Optional properties:
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -106,8 +106,9 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
|
|||
|
||||
bt_dev_dbg(hdev, "QCA pre shutdown cmd");
|
||||
|
||||
skb = __hci_cmd_sync(hdev, QCA_PRE_SHUTDOWN_CMD, 0,
|
||||
NULL, HCI_INIT_TIMEOUT);
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -435,6 +435,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 +524,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;
|
||||
|
@ -1175,6 +1206,13 @@ static int btusb_open(struct hci_dev *hdev)
|
|||
*/
|
||||
device_wakeup_enable(&data->udev->dev);
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
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,6 +1276,11 @@ static int btusb_close(struct hci_dev *hdev)
|
|||
goto failed;
|
||||
|
||||
data->intf->needs_remote_wakeup = 0;
|
||||
|
||||
/* Enable remote wake up for auto-suspend */
|
||||
if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
|
||||
data->intf->needs_remote_wakeup = 1;
|
||||
|
||||
device_wakeup_disable(&data->udev->dev);
|
||||
usb_autopm_put_interface(data->intf);
|
||||
|
||||
|
@ -3770,12 +3813,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
|
||||
|
||||
|
@ -3949,6 +3993,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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" },
|
||||
{ },
|
||||
|
|
|
@ -502,26 +502,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;
|
||||
|
||||
|
@ -1261,6 +1242,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 +1312,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,
|
||||
|
@ -1389,6 +1375,8 @@ static int qca_power_off(struct hci_dev *hdev)
|
|||
/* Perform pre shutdown command */
|
||||
qca_send_pre_shutdown_cmd(hdev);
|
||||
|
||||
usleep_range(8000, 10000);
|
||||
|
||||
qca_power_shutdown(hu);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -303,7 +303,7 @@ static void ms_ff_worker(struct work_struct *work)
|
|||
r->magnitude[MAGNITUDE_WEAK] = ms->weak; /* right actuator */
|
||||
|
||||
ret = hid_hw_output_report(hdev, (__u8 *)r, sizeof(*r));
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
hid_warn(hdev, "failed to send FF report\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -1517,6 +1517,8 @@ void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c);
|
|||
#define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04
|
||||
#define DISCOV_BREDR_INQUIRY_LEN 0x08
|
||||
#define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */
|
||||
#define DISCOV_LE_FAST_ADV_INT_MIN 100 /* msec */
|
||||
#define DISCOV_LE_FAST_ADV_INT_MAX 150 /* msec */
|
||||
|
||||
void mgmt_fill_version_info(void *ver);
|
||||
int mgmt_new_settings(struct hci_dev *hdev);
|
||||
|
|
|
@ -583,7 +583,7 @@ static const struct net_device_ops netdev_ops = {
|
|||
.ndo_start_xmit = bt_xmit,
|
||||
};
|
||||
|
||||
static struct header_ops header_ops = {
|
||||
static const struct header_ops header_ops = {
|
||||
.create = header_create,
|
||||
};
|
||||
|
||||
|
|
|
@ -1054,6 +1054,7 @@ void __hci_req_enable_advertising(struct hci_request *req)
|
|||
struct hci_cp_le_set_adv_param cp;
|
||||
u8 own_addr_type, enable = 0x01;
|
||||
bool connectable;
|
||||
u16 adv_min_interval, adv_max_interval;
|
||||
u32 flags;
|
||||
|
||||
flags = get_adv_instance_flags(hdev, hdev->cur_adv_instance);
|
||||
|
@ -1087,16 +1088,30 @@ void __hci_req_enable_advertising(struct hci_request *req)
|
|||
return;
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
cp.min_interval = cpu_to_le16(hdev->le_adv_min_interval);
|
||||
cp.max_interval = cpu_to_le16(hdev->le_adv_max_interval);
|
||||
|
||||
if (connectable)
|
||||
if (connectable) {
|
||||
cp.type = LE_ADV_IND;
|
||||
else if (get_cur_adv_instance_scan_rsp_len(hdev))
|
||||
cp.type = LE_ADV_SCAN_IND;
|
||||
else
|
||||
cp.type = LE_ADV_NONCONN_IND;
|
||||
|
||||
adv_min_interval = hdev->le_adv_min_interval;
|
||||
adv_max_interval = hdev->le_adv_max_interval;
|
||||
} else {
|
||||
if (get_cur_adv_instance_scan_rsp_len(hdev))
|
||||
cp.type = LE_ADV_SCAN_IND;
|
||||
else
|
||||
cp.type = LE_ADV_NONCONN_IND;
|
||||
|
||||
if (!hci_dev_test_flag(hdev, HCI_DISCOVERABLE) ||
|
||||
hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) {
|
||||
adv_min_interval = DISCOV_LE_FAST_ADV_INT_MIN;
|
||||
adv_max_interval = DISCOV_LE_FAST_ADV_INT_MAX;
|
||||
} else {
|
||||
adv_min_interval = hdev->le_adv_min_interval;
|
||||
adv_max_interval = hdev->le_adv_max_interval;
|
||||
}
|
||||
}
|
||||
|
||||
cp.min_interval = cpu_to_le16(adv_min_interval);
|
||||
cp.max_interval = cpu_to_le16(adv_max_interval);
|
||||
cp.own_address_type = own_addr_type;
|
||||
cp.channel_map = hdev->le_adv_channel_map;
|
||||
|
||||
|
|
|
@ -267,7 +267,7 @@ static int hidp_get_raw_report(struct hid_device *hid,
|
|||
set_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
|
||||
data[0] = report_number;
|
||||
ret = hidp_send_ctrl_message(session, report_type, data, 1);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Wait for the return of the report. The returned report
|
||||
|
@ -343,7 +343,7 @@ static int hidp_set_raw_report(struct hid_device *hid, unsigned char reportnum,
|
|||
data[0] = reportnum;
|
||||
set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
|
||||
ret = hidp_send_ctrl_message(session, report_type, data, count);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Wait for the ACK from the device. */
|
||||
|
|
|
@ -2588,7 +2588,6 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
{
|
||||
struct mgmt_rp_get_connections *rp;
|
||||
struct hci_conn *c;
|
||||
size_t rp_len;
|
||||
int err;
|
||||
u16 i;
|
||||
|
||||
|
@ -2608,8 +2607,7 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
i++;
|
||||
}
|
||||
|
||||
rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
|
||||
rp = kmalloc(rp_len, GFP_KERNEL);
|
||||
rp = kmalloc(struct_size(rp, addr, i), GFP_KERNEL);
|
||||
if (!rp) {
|
||||
err = -ENOMEM;
|
||||
goto unlock;
|
||||
|
@ -2629,10 +2627,8 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
rp->conn_count = cpu_to_le16(i);
|
||||
|
||||
/* Recalculate length in case of filtered SCO connections, etc */
|
||||
rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
|
||||
|
||||
err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONNECTIONS, 0, rp,
|
||||
rp_len);
|
||||
struct_size(rp, addr, i));
|
||||
|
||||
kfree(rp);
|
||||
|
||||
|
|
Loading…
Reference in New Issue