diff options
author | Ingo Molnar <mingo@kernel.org> | 2017-03-01 09:02:26 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-03-01 09:02:26 +0100 |
commit | 0871d5a66da5c41151e0896a90298b163e42f2e0 (patch) | |
tree | 1ba71fab9016cb28bb9d18ffd62b6b744f2f761c /drivers/bluetooth | |
parent | x86/boot: Fix pr_debug() API braindamage (diff) | |
parent | Merge tag 'for-linus-4.11' of git://git.code.sf.net/p/openipmi/linux-ipmi (diff) | |
download | linux-0871d5a66da5c41151e0896a90298b163e42f2e0.tar.xz linux-0871d5a66da5c41151e0896a90298b163e42f2e0.zip |
Merge branch 'linus' into WIP.x86/boot, to fix up conflicts and to pick up updates
Conflicts:
arch/x86/xen/setup.c
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/Kconfig | 2 | ||||
-rw-r--r-- | drivers/bluetooth/ath3k.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/btbcm.c | 3 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_main.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.c | 14 | ||||
-rw-r--r-- | drivers/bluetooth/btqcomsmd.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 164 | ||||
-rw-r--r-- | drivers/bluetooth/hci_bcm.c | 68 | ||||
-rw-r--r-- | drivers/bluetooth/hci_qca.c | 4 |
9 files changed, 217 insertions, 43 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 3cc9bff9d99d..c2c14a12713b 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -344,7 +344,7 @@ config BT_WILINK config BT_QCOMSMD tristate "Qualcomm SMD based HCI support" - depends on QCOM_SMD && QCOM_WCNSS_CTRL + depends on (QCOM_SMD && QCOM_WCNSS_CTRL) || COMPILE_TEST select BT_QCA help Qualcomm SMD based HCI driver. diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index fadba88745dc..b793853ff05f 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -94,6 +94,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x300f) }, { USB_DEVICE(0x04CA, 0x3010) }, { USB_DEVICE(0x04CA, 0x3014) }, + { USB_DEVICE(0x04CA, 0x3018) }, { USB_DEVICE(0x0930, 0x0219) }, { USB_DEVICE(0x0930, 0x021c) }, { USB_DEVICE(0x0930, 0x0220) }, @@ -162,6 +163,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index fdb44829ab6f..ba3dd2eafc09 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -178,6 +178,9 @@ static int btbcm_reset(struct hci_dev *hdev) } kfree_skb(skb); + /* 100 msec delay for module to complete reset process */ + msleep(100); + return 0; } diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index e6a85f0e6309..c38cb5b91291 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -502,7 +502,7 @@ static int btmrvl_download_cal_data(struct btmrvl_private *priv, ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data, BT_CAL_HDR_LEN + len); if (ret) - BT_ERR("Failed to download caibration data"); + BT_ERR("Failed to download calibration data"); return 0; } diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index d02f2c14df32..08e01f002bad 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -97,11 +97,11 @@ static int btmrvl_sdio_probe_of(struct device *dev, cfg->irq_bt = irq_of_parse_and_map(card->plt_of_node, 0); if (!cfg->irq_bt) { dev_err(dev, "fail to parse irq_bt from device tree"); + cfg->irq_bt = -1; } else { ret = devm_request_irq(dev, cfg->irq_bt, btmrvl_wake_irq_bt, - IRQF_TRIGGER_LOW, - "bt_wake", cfg); + 0, "bt_wake", cfg); if (ret) { dev_err(dev, "Failed to request irq_bt %d (%d)\n", @@ -1624,7 +1624,7 @@ static int btmrvl_sdio_suspend(struct device *dev) if (priv->adapter->hs_state != HS_ACTIVATED) { if (btmrvl_enable_hs(priv)) { - BT_ERR("HS not actived, suspend failed!"); + BT_ERR("HS not activated, suspend failed!"); priv->adapter->is_suspending = false; return -EBUSY; } @@ -1682,8 +1682,12 @@ static int btmrvl_sdio_resume(struct device *dev) /* Disable platform specific wakeup interrupt */ if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) { disable_irq_wake(card->plt_wake_cfg->irq_bt); - if (!card->plt_wake_cfg->wake_by_bt) - disable_irq(card->plt_wake_cfg->irq_bt); + disable_irq(card->plt_wake_cfg->irq_bt); + if (card->plt_wake_cfg->wake_by_bt) + /* Undo our disable, since interrupt handler already + * did this. + */ + enable_irq(card->plt_wake_cfg->irq_bt); } return 0; diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c index 08c2c93887c1..8d4868af9bbd 100644 --- a/drivers/bluetooth/btqcomsmd.c +++ b/drivers/bluetooth/btqcomsmd.c @@ -165,6 +165,7 @@ static const struct of_device_id btqcomsmd_of_match[] = { { .compatible = "qcom,wcnss-bt", }, { }, }; +MODULE_DEVICE_TABLE(of, btqcomsmd_of_match); static struct platform_driver btqcomsmd_driver = { .probe = btqcomsmd_probe, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 2f633df9f4e6..1c8094ef3f22 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -24,6 +24,8 @@ #include <linux/module.h> #include <linux/usb.h> #include <linux/firmware.h> +#include <linux/of_device.h> +#include <linux/of_irq.h> #include <asm/unaligned.h> #include <net/bluetooth/bluetooth.h> @@ -130,6 +132,10 @@ static const struct usb_device_id btusb_table[] = { /* Broadcom BCM43142A0 (Foxconn/Lenovo) */ { USB_DEVICE(0x105b, 0xe065), .driver_info = BTUSB_BCM_PATCHRAM }, + /* Broadcom BCM920703 (HTC Vive) */ + { USB_VENDOR_AND_INTERFACE_INFO(0x0bb4, 0xff, 0x01, 0x01), + .driver_info = BTUSB_BCM_PATCHRAM }, + /* Foxconn - Hon Hai */ { USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01), .driver_info = BTUSB_BCM_PATCHRAM }, @@ -154,6 +160,10 @@ static const struct usb_device_id btusb_table[] = { { USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01), .driver_info = BTUSB_BCM_PATCHRAM }, + /* Dell Computer - Broadcom based */ + { USB_VENDOR_AND_INTERFACE_INFO(0x413c, 0xff, 0x01, 0x01), + .driver_info = BTUSB_BCM_PATCHRAM }, + /* Toshiba Corp - Broadcom based */ { USB_VENDOR_AND_INTERFACE_INFO(0x0930, 0xff, 0x01, 0x01), .driver_info = BTUSB_BCM_PATCHRAM }, @@ -209,6 +219,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, @@ -369,6 +380,7 @@ static const struct usb_device_id blacklist_table[] = { #define BTUSB_BOOTING 9 #define BTUSB_RESET_RESUME 10 #define BTUSB_DIAG_RUNNING 11 +#define BTUSB_OOB_WAKE_ENABLED 12 struct btusb_data { struct hci_dev *hdev; @@ -416,6 +428,8 @@ struct btusb_data { int (*recv_bulk)(struct btusb_data *data, void *buffer, int count); int (*setup_on_usb)(struct hci_dev *hdev); + + int oob_wake_irq; /* irq for out-of-band wake-on-bt */ }; static inline void btusb_free_frags(struct btusb_data *data) @@ -2338,6 +2352,50 @@ static int btusb_shutdown_intel(struct hci_dev *hdev) return 0; } +#ifdef CONFIG_PM +/* Configure an out-of-band gpio as wake-up pin, if specified in device tree */ +static int marvell_config_oob_wake(struct hci_dev *hdev) +{ + struct sk_buff *skb; + struct btusb_data *data = hci_get_drvdata(hdev); + struct device *dev = &data->udev->dev; + u16 pin, gap, opcode; + int ret; + u8 cmd[5]; + + /* Move on if no wakeup pin specified */ + if (of_property_read_u16(dev->of_node, "marvell,wakeup-pin", &pin) || + of_property_read_u16(dev->of_node, "marvell,wakeup-gap-ms", &gap)) + return 0; + + /* Vendor specific command to configure a GPIO as wake-up pin */ + opcode = hci_opcode_pack(0x3F, 0x59); + cmd[0] = opcode & 0xFF; + cmd[1] = opcode >> 8; + cmd[2] = 2; /* length of parameters that follow */ + cmd[3] = pin; + cmd[4] = gap; /* time in ms, for which wakeup pin should be asserted */ + + skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL); + if (!skb) { + bt_dev_err(hdev, "%s: No memory\n", __func__); + return -ENOMEM; + } + + memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd)); + hci_skb_pkt_type(skb) = HCI_COMMAND_PKT; + + ret = btusb_send_frame(hdev, skb); + if (ret) { + bt_dev_err(hdev, "%s: configuration failed\n", __func__); + kfree_skb(skb); + return ret; + } + + return 0; +} +#endif + static int btusb_set_bdaddr_marvell(struct hci_dev *hdev, const bdaddr_t *bdaddr) { @@ -2728,6 +2786,66 @@ static int btusb_bcm_set_diag(struct hci_dev *hdev, bool enable) } #endif +#ifdef CONFIG_PM +static irqreturn_t btusb_oob_wake_handler(int irq, void *priv) +{ + struct btusb_data *data = priv; + + pm_wakeup_event(&data->udev->dev, 0); + + /* Disable only if not already disabled (keep it balanced) */ + if (test_and_clear_bit(BTUSB_OOB_WAKE_ENABLED, &data->flags)) { + disable_irq_nosync(irq); + disable_irq_wake(irq); + } + return IRQ_HANDLED; +} + +static const struct of_device_id btusb_match_table[] = { + { .compatible = "usb1286,204e" }, + { } +}; +MODULE_DEVICE_TABLE(of, btusb_match_table); + +/* Use an oob wakeup pin? */ +static int btusb_config_oob_wake(struct hci_dev *hdev) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + struct device *dev = &data->udev->dev; + int irq, ret; + + clear_bit(BTUSB_OOB_WAKE_ENABLED, &data->flags); + + if (!of_match_device(btusb_match_table, dev)) + return 0; + + /* Move on if no IRQ specified */ + irq = of_irq_get_byname(dev->of_node, "wakeup"); + if (irq <= 0) { + bt_dev_dbg(hdev, "%s: no OOB Wakeup IRQ in DT", __func__); + return 0; + } + + ret = devm_request_irq(&hdev->dev, irq, btusb_oob_wake_handler, + 0, "OOB Wake-on-BT", data); + if (ret) { + bt_dev_err(hdev, "%s: IRQ request failed", __func__); + return ret; + } + + ret = device_init_wakeup(dev, true); + if (ret) { + bt_dev_err(hdev, "%s: failed to init_wakeup", __func__); + return ret; + } + + data->oob_wake_irq = irq; + disable_irq(irq); + bt_dev_info(hdev, "OOB Wake-on-BT configured at IRQ %u", irq); + return 0; +} +#endif + static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -2849,6 +2967,18 @@ static int btusb_probe(struct usb_interface *intf, hdev->send = btusb_send_frame; hdev->notify = btusb_notify; +#ifdef CONFIG_PM + err = btusb_config_oob_wake(hdev); + if (err) + goto out_free_dev; + + /* Marvell devices may need a specific chip configuration */ + if (id->driver_info & BTUSB_MARVELL && data->oob_wake_irq) { + err = marvell_config_oob_wake(hdev); + if (err) + goto out_free_dev; + } +#endif if (id->driver_info & BTUSB_CW6622) set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks); @@ -2991,18 +3121,15 @@ static int btusb_probe(struct usb_interface *intf, err = usb_set_interface(data->udev, 0, 0); if (err < 0) { BT_ERR("failed to set interface 0, alt 0 %d", err); - hci_free_dev(hdev); - return err; + goto out_free_dev; } } if (data->isoc) { err = usb_driver_claim_interface(&btusb_driver, data->isoc, data); - if (err < 0) { - hci_free_dev(hdev); - return err; - } + if (err < 0) + goto out_free_dev; } #ifdef CONFIG_BT_HCIBTUSB_BCM @@ -3016,14 +3143,16 @@ static int btusb_probe(struct usb_interface *intf, #endif err = hci_register_dev(hdev); - if (err < 0) { - hci_free_dev(hdev); - return err; - } + if (err < 0) + goto out_free_dev; usb_set_intfdata(intf, data); return 0; + +out_free_dev: + hci_free_dev(hdev); + return err; } static void btusb_disconnect(struct usb_interface *intf) @@ -3062,6 +3191,9 @@ static void btusb_disconnect(struct usb_interface *intf) usb_driver_release_interface(&btusb_driver, data->isoc); } + if (data->oob_wake_irq) + device_init_wakeup(&data->udev->dev, false); + hci_free_dev(hdev); } @@ -3090,6 +3222,12 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) btusb_stop_traffic(data); usb_kill_anchored_urbs(&data->tx_anchor); + if (data->oob_wake_irq && device_may_wakeup(&data->udev->dev)) { + set_bit(BTUSB_OOB_WAKE_ENABLED, &data->flags); + enable_irq_wake(data->oob_wake_irq); + enable_irq(data->oob_wake_irq); + } + /* Optionally request a device reset on resume, but only when * wakeups are disabled. If wakeups are enabled we assume the * device will stay powered up throughout suspend. @@ -3127,6 +3265,12 @@ static int btusb_resume(struct usb_interface *intf) if (--data->suspend_count) return 0; + /* Disable only if not already disabled (keep it balanced) */ + if (test_and_clear_bit(BTUSB_OOB_WAKE_ENABLED, &data->flags)) { + disable_irq(data->oob_wake_irq); + disable_irq_wake(data->oob_wake_irq); + } + if (!test_bit(HCI_RUNNING, &hdev->flags)) goto done; diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 8f6c23c20c52..5262a2077d7a 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -618,14 +618,25 @@ unlock: } #endif -static const struct acpi_gpio_params device_wakeup_gpios = { 0, 0, false }; -static const struct acpi_gpio_params shutdown_gpios = { 1, 0, false }; -static const struct acpi_gpio_params host_wakeup_gpios = { 2, 0, false }; - -static const struct acpi_gpio_mapping acpi_bcm_default_gpios[] = { - { "device-wakeup-gpios", &device_wakeup_gpios, 1 }, - { "shutdown-gpios", &shutdown_gpios, 1 }, - { "host-wakeup-gpios", &host_wakeup_gpios, 1 }, +static const struct acpi_gpio_params int_last_device_wakeup_gpios = { 0, 0, false }; +static const struct acpi_gpio_params int_last_shutdown_gpios = { 1, 0, false }; +static const struct acpi_gpio_params int_last_host_wakeup_gpios = { 2, 0, false }; + +static const struct acpi_gpio_mapping acpi_bcm_int_last_gpios[] = { + { "device-wakeup-gpios", &int_last_device_wakeup_gpios, 1 }, + { "shutdown-gpios", &int_last_shutdown_gpios, 1 }, + { "host-wakeup-gpios", &int_last_host_wakeup_gpios, 1 }, + { }, +}; + +static const struct acpi_gpio_params int_first_host_wakeup_gpios = { 0, 0, false }; +static const struct acpi_gpio_params int_first_device_wakeup_gpios = { 1, 0, false }; +static const struct acpi_gpio_params int_first_shutdown_gpios = { 2, 0, false }; + +static const struct acpi_gpio_mapping acpi_bcm_int_first_gpios[] = { + { "device-wakeup-gpios", &int_first_device_wakeup_gpios, 1 }, + { "shutdown-gpios", &int_first_shutdown_gpios, 1 }, + { "host-wakeup-gpios", &int_first_host_wakeup_gpios, 1 }, { }, }; @@ -692,12 +703,19 @@ static int bcm_acpi_probe(struct bcm_device *dev) struct platform_device *pdev = dev->pdev; LIST_HEAD(resources); const struct dmi_system_id *dmi_id; + const struct acpi_gpio_mapping *gpio_mapping = acpi_bcm_int_last_gpios; + const struct acpi_device_id *id; int ret; - /* Retrieve GPIO data */ dev->name = dev_name(&pdev->dev); + + /* Retrieve GPIO data */ + id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev); + if (id) + gpio_mapping = (const struct acpi_gpio_mapping *) id->driver_data; + ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev), - acpi_bcm_default_gpios); + gpio_mapping); if (ret) return ret; @@ -822,20 +840,22 @@ static const struct hci_uart_proto bcm_proto = { #ifdef CONFIG_ACPI static const struct acpi_device_id bcm_acpi_match[] = { - { "BCM2E1A", 0 }, - { "BCM2E39", 0 }, - { "BCM2E3A", 0 }, - { "BCM2E3D", 0 }, - { "BCM2E3F", 0 }, - { "BCM2E40", 0 }, - { "BCM2E54", 0 }, - { "BCM2E55", 0 }, - { "BCM2E64", 0 }, - { "BCM2E65", 0 }, - { "BCM2E67", 0 }, - { "BCM2E71", 0 }, - { "BCM2E7B", 0 }, - { "BCM2E7C", 0 }, + { "BCM2E1A", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E39", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E3A", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E3D", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E3F", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E40", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E54", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E55", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E64", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E65", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E67", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E71", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E7B", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E7C", (kernel_ulong_t)&acpi_bcm_int_last_gpios }, + { "BCM2E95", (kernel_ulong_t)&acpi_bcm_int_first_gpios }, + { "BCM2E96", (kernel_ulong_t)&acpi_bcm_int_first_gpios }, { }, }; MODULE_DEVICE_TABLE(acpi, bcm_acpi_match); diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 05c230719a47..f242dfd0c2e2 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -335,7 +335,7 @@ static void hci_ibs_tx_idle_timeout(unsigned long arg) /* Fall through */ default: - BT_ERR("Spurrious timeout tx state %d", qca->tx_ibs_state); + BT_ERR("Spurious timeout tx state %d", qca->tx_ibs_state); break; } @@ -373,7 +373,7 @@ static void hci_ibs_wake_retrans_timeout(unsigned long arg) /* Fall through */ default: - BT_ERR("Spurrious timeout tx state %d", qca->tx_ibs_state); + BT_ERR("Spurious timeout tx state %d", qca->tx_ibs_state); break; } |