diff options
39 files changed, 5309 insertions, 266 deletions
diff --git a/Documentation/devicetree/bindings/net/ieee802154/ca8210.txt b/Documentation/devicetree/bindings/net/ieee802154/ca8210.txt new file mode 100644 index 000000000000..a1046e636fa1 --- /dev/null +++ b/Documentation/devicetree/bindings/net/ieee802154/ca8210.txt @@ -0,0 +1,28 @@ +* CA8210 IEEE 802.15.4 * + +Required properties: + - compatible: Should be "cascoda,ca8210" + - reg: Controlling chip select + - spi-max-frequency: Maximum clock speed, should be *less than* + 4000000 + - spi-cpol: Requires inverted clock polarity + - reset-gpio: GPIO attached to reset + - irq-gpio: GPIO attached to IRQ +Optional properties: + - extclock-enable: Include for the ca8210 to route its 16MHz clock + to an output + - extclock-freq: Frequency in Hz of the external clock + - extclock-gpio: GPIO of the ca8210 to output the clock on + +Example: + ca8210@0 { + compatible = "cascoda,ca8210"; + reg = <0>; + spi-max-frequency = <3000000>; + spi-cpol; + reset-gpio = <&gpio1 1 GPIO_ACTIVE_HIGH>; + irq-gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>; + extclock-enable; + extclock-freq = 16000000; + extclock-gpio = 2; + }; diff --git a/Documentation/devicetree/bindings/net/nokia-bluetooth.txt b/Documentation/devicetree/bindings/net/nokia-bluetooth.txt new file mode 100644 index 000000000000..42be7dc9a70b --- /dev/null +++ b/Documentation/devicetree/bindings/net/nokia-bluetooth.txt @@ -0,0 +1,51 @@ +Nokia Bluetooth Chips +--------------------- + +Nokia phones often come with UART connected bluetooth chips from different +vendors and modified device API. Those devices speak a protocol named H4+ +(also known as h4p) by Nokia, which is similar to the H4 protocol from the +Bluetooth standard. In addition to the H4 protocol it specifies two more +UART status lines for wakeup of UART transceivers to improve power management +and a few new packet types used to negotiate uart speed. + +Required properties: + + - compatible: should contain "nokia,h4p-bluetooth" as well as one of the following: + * "brcm,bcm2048-nokia" + * "ti,wl1271-bluetooth-nokia" + - reset-gpios: GPIO specifier, used to reset the BT module (active low) + - bluetooth-wakeup-gpios: GPIO specifier, used to wakeup the BT module (active high) + - host-wakeup-gpios: GPIO specifier, used to wakeup the host processor (active high) + - clock-names: should be "sysclk" + - clocks: should contain a clock specifier for every name in clock-names + +Optional properties: + + - None + +Example: + +/ { + /* controlled (enabled/disabled) directly by BT module */ + bluetooth_clk: vctcxo { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <38400000>; + }; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + + bluetooth { + compatible = "ti,wl1271-bluetooth-nokia", "nokia,h4p-bluetooth"; + + reset-gpios = <&gpio1 26 GPIO_ACTIVE_LOW>; /* gpio26 */ + host-wakeup-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* gpio101 */ + bluetooth-wakeup-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; /* gpio37 */ + + clocks = <&bluetooth_clk>; + clock-names = "sysclk"; + }; +}; diff --git a/Documentation/devicetree/bindings/net/ti,wilink-st.txt b/Documentation/devicetree/bindings/net/ti,wilink-st.txt new file mode 100644 index 000000000000..cbad73a84ac4 --- /dev/null +++ b/Documentation/devicetree/bindings/net/ti,wilink-st.txt @@ -0,0 +1,35 @@ +TI WiLink 7/8 (wl12xx/wl18xx) Shared Transport BT/FM/GPS devices + +TI WiLink devices have a UART interface for providing Bluetooth, FM radio, +and GPS over what's called "shared transport". The shared transport is +standard BT HCI protocol with additional channels for the other functions. + +These devices also have a separate WiFi interface as described in +wireless/ti,wlcore.txt. + +This bindings follows the UART slave device binding in +../serial/slave-device.txt. + +Required properties: + - compatible: should be one of the following: + "ti,wl1271-st" + "ti,wl1273-st" + "ti,wl1831-st" + "ti,wl1835-st" + "ti,wl1837-st" + +Optional properties: + - enable-gpios : GPIO signal controlling enabling of BT. Active high. + - vio-supply : Vio input supply (1.8V) + - vbat-supply : Vbat input supply (2.9-4.8V) + +Example: + +&serial0 { + compatible = "ns16550a"; + ... + bluetooth { + compatible = "ti,wl1835-st"; + enable-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + }; +}; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index ec0bfb9bbebd..36b4d8a3fe6c 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -51,6 +51,7 @@ brcm Broadcom Corporation buffalo Buffalo, Inc. calxeda Calxeda capella Capella Microsystems, Inc +cascoda Cascoda, Ltd. cavium Cavium, Inc. cdns Cadence Design Systems Inc. ceva Ceva, Inc. diff --git a/MAINTAINERS b/MAINTAINERS index 197387863297..7b4b82865179 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2944,6 +2944,15 @@ W: http://www.linux-c6x.org/wiki/index.php/Main_Page S: Maintained F: arch/c6x/ +CA8210 IEEE-802.15.4 RADIO DRIVER +M: Harry Morris <h.morris@cascoda.com> +M: linuxdev@cascoda.com +L: linux-wpan@vger.kernel.org +W: https://github.com/Cascoda/ca8210-linux.git +S: Maintained +F: drivers/net/ieee802154/ca8210.c +F: Documentation/devicetree/bindings/net/ieee802154/ca8210.txt + CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS M: David Howells <dhowells@redhat.com> L: linux-cachefs@redhat.com (moderated for non-subscribers) diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts index dba3c131c62c..9b4ba7169210 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts @@ -98,6 +98,11 @@ assigned-clocks = <&sys_ctrl HI6220_UART1_SRC>; assigned-clock-rates = <150000000>; status = "ok"; + + bluetooth { + compatible = "ti,wl1835-st"; + enable-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + }; }; uart2: uart@f7112000 { diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index a6a9dd4d0eef..8aafbed9e160 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -86,6 +86,18 @@ config BT_HCIUART_H4 Say Y here to compile support for HCI UART (H4) protocol. +config BT_HCIUART_NOKIA + tristate "UART Nokia H4+ protocol support" + depends on BT_HCIUART + depends on SERIAL_DEV_BUS + depends on PM + help + Nokia H4+ is serial protocol for communication between Bluetooth + device and host. This protocol is required for Bluetooth devices + with UART interface in Nokia devices. + + Say Y here to compile support for Nokia's H4+ protocol. + config BT_HCIUART_BCSP bool "BCSP protocol support" depends on BT_HCIUART diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile index 80627187c8b6..a7f237320f4b 100644 --- a/drivers/bluetooth/Makefile +++ b/drivers/bluetooth/Makefile @@ -25,10 +25,13 @@ obj-$(CONFIG_BT_BCM) += btbcm.o obj-$(CONFIG_BT_RTL) += btrtl.o obj-$(CONFIG_BT_QCA) += btqca.o +obj-$(CONFIG_BT_HCIUART_NOKIA) += hci_nokia.o + btmrvl-y := btmrvl_main.o btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o hci_uart-y := hci_ldisc.o +hci_uart-$(CONFIG_SERIAL_DEV_BUS) += hci_serdev.o hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o hci_uart-$(CONFIG_BT_HCIUART_BCSP) += hci_bcsp.o hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index c0b3b5576992..007c0a45f31b 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -695,9 +695,8 @@ static int bluecard_open(struct bluecard_info *info) spin_lock_init(&(info->lock)); - init_timer(&(info->timer)); - info->timer.function = &bluecard_activity_led_timeout; - info->timer.data = (u_long)info; + setup_timer(&(info->timer), &bluecard_activity_led_timeout, + (u_long)info); skb_queue_head_init(&(info->txq)); diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 08e01f002bad..eb794f08b238 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -20,6 +20,7 @@ #include <linux/firmware.h> #include <linux/slab.h> +#include <linux/suspend.h> #include <linux/mmc/sdio_ids.h> #include <linux/mmc/sdio_func.h> @@ -60,13 +61,15 @@ static const struct of_device_id btmrvl_sdio_of_match_table[] = { static irqreturn_t btmrvl_wake_irq_bt(int irq, void *priv) { - struct btmrvl_plt_wake_cfg *cfg = priv; + struct btmrvl_sdio_card *card = priv; + struct btmrvl_plt_wake_cfg *cfg = card->plt_wake_cfg; - if (cfg->irq_bt >= 0) { - pr_info("%s: wake by bt", __func__); - cfg->wake_by_bt = true; - disable_irq_nosync(irq); - } + pr_info("%s: wake by bt", __func__); + cfg->wake_by_bt = true; + disable_irq_nosync(irq); + + pm_wakeup_event(&card->func->dev, 0); + pm_system_wakeup(); return IRQ_HANDLED; } @@ -101,7 +104,7 @@ static int btmrvl_sdio_probe_of(struct device *dev, } else { ret = devm_request_irq(dev, cfg->irq_bt, btmrvl_wake_irq_bt, - 0, "bt_wake", cfg); + 0, "bt_wake", card); if (ret) { dev_err(dev, "Failed to request irq_bt %d (%d)\n", @@ -1574,7 +1577,7 @@ static void btmrvl_sdio_remove(struct sdio_func *func) MODULE_SHUTDOWN_REQ); btmrvl_sdio_disable_host_int(card); } - BT_DBG("unregester dev"); + BT_DBG("unregister dev"); card->priv->surprise_removed = true; btmrvl_sdio_unregister_dev(card); btmrvl_remove_card(card->priv); @@ -1625,6 +1628,13 @@ static int btmrvl_sdio_suspend(struct device *dev) if (priv->adapter->hs_state != HS_ACTIVATED) { if (btmrvl_enable_hs(priv)) { BT_ERR("HS not activated, suspend failed!"); + /* 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); + disable_irq(card->plt_wake_cfg->irq_bt); + } + priv->adapter->is_suspending = false; return -EBUSY; } @@ -1637,10 +1647,10 @@ static int btmrvl_sdio_suspend(struct device *dev) if (priv->adapter->hs_state == HS_ACTIVATED) { BT_DBG("suspend with MMC_PM_KEEP_POWER"); return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); - } else { - BT_DBG("suspend without MMC_PM_KEEP_POWER"); - return 0; } + + BT_DBG("suspend without MMC_PM_KEEP_POWER"); + return 0; } static int btmrvl_sdio_resume(struct device *dev) diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index fc9b25703c67..8279094dd713 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -275,11 +275,8 @@ static int rtl_load_config(struct hci_dev *hdev, const char *name, u8 **buff) BT_INFO("%s: rtl: loading %s", hdev->name, name); ret = request_firmware(&fw, name, &hdev->dev); - if (ret < 0) { - BT_ERR("%s: Failed to load %s", hdev->name, name); + if (ret < 0) return ret; - } - ret = fw->size; *buff = kmemdup(fw->data, ret, GFP_KERNEL); @@ -331,6 +328,7 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, u8 *cfg_buff = NULL; u8 *tbuff; char *cfg_name = NULL; + bool config_needed = false; switch (lmp_subver) { case RTL_ROM_LMP_8723B: @@ -344,6 +342,7 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, break; case RTL_ROM_LMP_8822B: cfg_name = "rtl_bt/rtl8822b_config.bin"; + config_needed = true; break; default: BT_ERR("%s: rtl: no config according to lmp_subver %04x", @@ -353,8 +352,12 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, if (cfg_name) { cfg_sz = rtl_load_config(hdev, cfg_name, &cfg_buff); - if (cfg_sz < 0) + if (cfg_sz < 0) { cfg_sz = 0; + if (config_needed) + BT_ERR("Necessary config file %s not found\n", + cfg_name); + } } else cfg_sz = 0; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 1c8094ef3f22..7fa373b428f8 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -26,6 +26,7 @@ #include <linux/firmware.h> #include <linux/of_device.h> #include <linux/of_irq.h> +#include <linux/suspend.h> #include <asm/unaligned.h> #include <net/bluetooth/bluetooth.h> @@ -262,6 +263,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe009), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME }, + { USB_DEVICE(0x0cf3, 0xe301), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x0489, 0xe092), .driver_info = BTUSB_QCA_ROME }, { USB_DEVICE(0x04ca, 0x3011), .driver_info = BTUSB_QCA_ROME }, @@ -328,6 +330,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x1286, 0x204e), .driver_info = BTUSB_MARVELL }, /* Intel Bluetooth devices */ + { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW }, { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR }, { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL }, { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL }, @@ -2024,13 +2027,18 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) return -EINVAL; } - /* At the moment the iBT 3.0 hardware variants 0x0b (LnP/SfP) - * and 0x0c (WsP) are supported by this firmware loading method. + /* Check for supported iBT hardware variants of this firmware + * loading method. * * This check has been put in place to ensure correct forward * compatibility options when newer hardware variants come along. */ - if (ver.hw_variant != 0x0b && ver.hw_variant != 0x0c) { + switch (ver.hw_variant) { + case 0x0b: /* SfP */ + case 0x0c: /* WsP */ + case 0x12: /* ThP */ + break; + default: BT_ERR("%s: Unsupported Intel hardware variant (%u)", hdev->name, ver.hw_variant); return -EINVAL; @@ -2792,6 +2800,7 @@ static irqreturn_t btusb_oob_wake_handler(int irq, void *priv) struct btusb_data *data = priv; pm_wakeup_event(&data->udev->dev, 0); + pm_system_wakeup(); /* Disable only if not already disabled (keep it balanced) */ if (test_and_clear_bit(BTUSB_OOB_WAKE_ENABLED, &data->flags)) { diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 5262a2077d7a..f87bfdfee4ff 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -146,13 +146,13 @@ static bool bcm_device_exists(struct bcm_device *device) static int bcm_gpio_set_power(struct bcm_device *dev, bool powered) { if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled) - clk_enable(dev->clk); + clk_prepare_enable(dev->clk); gpiod_set_value(dev->shutdown, powered); gpiod_set_value(dev->device_wakeup, powered); if (!powered && !IS_ERR(dev->clk) && dev->clk_enabled) - clk_disable(dev->clk); + clk_disable_unprepare(dev->clk); dev->clk_enabled = powered; @@ -287,6 +287,9 @@ static int bcm_open(struct hci_uart *hu) hu->priv = bcm; + if (!hu->tty->dev) + goto out; + mutex_lock(&bcm_device_lock); list_for_each(p, &bcm_device_list) { struct bcm_device *dev = list_entry(p, struct bcm_device, list); @@ -307,7 +310,7 @@ static int bcm_open(struct hci_uart *hu) } mutex_unlock(&bcm_device_lock); - +out: return 0; } @@ -697,28 +700,14 @@ static int bcm_resource(struct acpi_resource *ares, void *data) /* Always tell the ACPI core to skip this resource */ return 1; } +#endif /* CONFIG_ACPI */ -static int bcm_acpi_probe(struct bcm_device *dev) +static int bcm_platform_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; 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), - gpio_mapping); - if (ret) - return ret; - dev->clk = devm_clk_get(&pdev->dev, NULL); dev->device_wakeup = devm_gpiod_get_optional(&pdev->dev, @@ -755,6 +744,33 @@ static int bcm_acpi_probe(struct bcm_device *dev) return -EINVAL; } + return 0; +} + +#ifdef CONFIG_ACPI +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 */ + 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), + gpio_mapping); + if (ret) + return ret; + + ret = bcm_platform_probe(dev); + if (ret) + return ret; + /* Retrieve UART ACPI info */ ret = acpi_dev_get_resources(ACPI_COMPANION(&dev->pdev->dev), &resources, bcm_resource, dev); @@ -789,7 +805,10 @@ static int bcm_probe(struct platform_device *pdev) dev->pdev = pdev; - ret = bcm_acpi_probe(dev); + if (has_acpi_companion(&pdev->dev)) + ret = bcm_acpi_probe(dev); + else + ret = bcm_platform_probe(dev); if (ret) return ret; diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 635597b6e168..82e5a32b87a4 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -171,9 +171,20 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb, const unsigned char *buffer, int count, const struct h4_recv_pkt *pkts, int pkts_count) { + struct hci_uart *hu = hci_get_drvdata(hdev); + u8 alignment = hu->alignment; + while (count) { int i, len; + /* remove padding bytes from buffer */ + for (; hu->padding && count > 0; hu->padding--) { + count--; + buffer++; + } + if (!count) + break; + if (!skb) { for (i = 0; i < pkts_count; i++) { if (buffer[0] != (&pkts[i])->type) @@ -253,11 +264,17 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb, } if (!dlen) { + hu->padding = (skb->len - 1) % alignment; + hu->padding = (alignment - hu->padding) % alignment; + /* No more data, complete frame */ (&pkts[i])->recv(hdev, skb); skb = NULL; } } else { + hu->padding = (skb->len - 1) % alignment; + hu->padding = (alignment - hu->padding) % alignment; + /* Complete frame */ (&pkts[i])->recv(hdev, skb); skb = NULL; diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index 9e271286c5e5..fa5099986f1b 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -307,6 +307,9 @@ static int intel_set_power(struct hci_uart *hu, bool powered) struct list_head *p; int err = -ENODEV; + if (!hu->tty->dev) + return err; + mutex_lock(&intel_device_list_lock); list_for_each(p, &intel_device_list) { @@ -379,6 +382,9 @@ static void intel_busy_work(struct work_struct *work) struct intel_data *intel = container_of(work, struct intel_data, busy_work); + if (!intel->hu->tty->dev) + return; + /* Link is busy, delay the suspend */ mutex_lock(&intel_device_list_lock); list_for_each(p, &intel_device_list) { @@ -601,12 +607,18 @@ static int intel_setup(struct hci_uart *hu) return -EINVAL; } - /* At the moment only the hardware variant iBT 3.0 (LnP/SfP) is - * supported by this firmware loading method. This check has been - * put in place to ensure correct forward compatibility options - * when newer hardware variants come along. - */ - if (ver.hw_variant != 0x0b) { + /* Check for supported iBT hardware variants of this firmware + * loading method. + * + * This check has been put in place to ensure correct forward + * compatibility options when newer hardware variants come along. + */ + switch (ver.hw_variant) { + case 0x0b: /* LnP */ + case 0x0c: /* WsP */ + case 0x12: /* ThP */ + break; + default: bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)", ver.hw_variant); return -EINVAL; @@ -699,11 +711,14 @@ static int intel_setup(struct hci_uart *hu) /* With this Intel bootloader only the hardware variant and device * revision information are used to select the right firmware. * - * Currently this bootloader support is limited to hardware variant - * iBT 3.0 (LnP/SfP) which is identified by the value 11 (0x0b). + * The firmware filename is ibt-<hw_variant>-<dev_revid>.sfi. + * + * Currently the supported hardware variants are: + * 11 (0x0b) for iBT 3.0 (LnP/SfP) */ - snprintf(fwname, sizeof(fwname), "intel/ibt-11-%u.sfi", - le16_to_cpu(params->dev_revid)); + snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.sfi", + le16_to_cpu(ver.hw_variant), + le16_to_cpu(params->dev_revid)); err = request_firmware(&fw, fwname, &hdev->dev); if (err < 0) { @@ -716,8 +731,9 @@ static int intel_setup(struct hci_uart *hu) bt_dev_info(hdev, "Found device firmware: %s", fwname); /* Save the DDC file name for later */ - snprintf(fwname, sizeof(fwname), "intel/ibt-11-%u.ddc", - le16_to_cpu(params->dev_revid)); + snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.ddc", + le16_to_cpu(ver.hw_variant), + le16_to_cpu(params->dev_revid)); kfree_skb(skb); @@ -889,6 +905,8 @@ done: list_for_each(p, &intel_device_list) { struct intel_device *dev = list_entry(p, struct intel_device, list); + if (!hu->tty->dev) + break; if (hu->tty->dev->parent == dev->pdev->dev.parent) { if (device_may_wakeup(&dev->pdev->dev)) { set_bit(STATE_LPM_ENABLED, &intel->flags); @@ -1056,6 +1074,9 @@ static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb) BT_DBG("hu %p skb %p", hu, skb); + if (!hu->tty->dev) + goto out_enqueue; + /* Be sure our controller is resumed and potential LPM transaction * completed before enqueuing any packet. */ @@ -1072,7 +1093,7 @@ static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb) } } mutex_unlock(&intel_device_list_lock); - +out_enqueue: skb_queue_tail(&intel->txq, skb); return 0; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 9497c469efd2..cec4438ede01 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -134,6 +134,7 @@ int hci_uart_tx_wakeup(struct hci_uart *hu) return 0; } +EXPORT_SYMBOL_GPL(hci_uart_tx_wakeup); static void hci_uart_write_work(struct work_struct *work) { @@ -318,25 +319,6 @@ void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed, hu->oper_speed = oper_speed; } -void hci_uart_init_tty(struct hci_uart *hu) -{ - struct tty_struct *tty = hu->tty; - struct ktermios ktermios; - - /* Bring the UART into a known 8 bits no parity hw fc state */ - ktermios = tty->termios; - ktermios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | - INLCR | IGNCR | ICRNL | IXON); - ktermios.c_oflag &= ~OPOST; - ktermios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - ktermios.c_cflag &= ~(CSIZE | PARENB); - ktermios.c_cflag |= CS8; - ktermios.c_cflag |= CRTSCTS; - - /* tty_set_termios() return not checked as it is always 0 */ - tty_set_termios(tty, &ktermios); -} - void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed) { struct tty_struct *tty = hu->tty; @@ -459,6 +441,10 @@ static int hci_uart_tty_open(struct tty_struct *tty) hu->tty = tty; tty->receive_room = 65536; |
