Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says: ==================== pull request: bluetooth-next 2017-02-19 Here's a set of Bluetooth patches for the 4.11 kernel: - New USB IDs to the btusb driver - Race fix in btmrvl driver - Added out-of-band wakeup support to the btusb driver - NULL dereference fix to bt_sock_recvmsg 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:
Коммит
c1ceee5efe
|
@ -0,0 +1,43 @@
|
|||
Generic Bluetooth controller over USB (btusb driver)
|
||||
---------------------------------------------------
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should comply with the format "usbVID,PID" specified in
|
||||
Documentation/devicetree/bindings/usb/usb-device.txt
|
||||
At the time of writing, the only OF supported devices
|
||||
(more may be added later) are:
|
||||
|
||||
"usb1286,204e" (Marvell 8997)
|
||||
|
||||
Also, vendors that use btusb may have device additional properties, e.g:
|
||||
Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt
|
||||
|
||||
Optional properties:
|
||||
|
||||
- interrupt-parent: phandle of the parent interrupt controller
|
||||
- interrupt-names: (see below)
|
||||
- interrupts : The interrupt specified by the name "wakeup" is the interrupt
|
||||
that shall be used for out-of-band wake-on-bt. Driver will
|
||||
request this interrupt for wakeup. During system suspend, the
|
||||
irq will be enabled so that the bluetooth chip can wakeup host
|
||||
platform out of band. During system resume, the irq will be
|
||||
disabled to make sure unnecessary interrupt is not received.
|
||||
|
||||
Example:
|
||||
|
||||
Following example uses irq pin number 3 of gpio0 for out of band wake-on-bt:
|
||||
|
||||
&usb_host1_ehci {
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mvl_bt1: bt@1 {
|
||||
compatible = "usb1286,204e";
|
||||
reg = <1>;
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupt-name = "wakeup";
|
||||
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
|
@ -1,16 +1,21 @@
|
|||
Marvell 8897/8997 (sd8897/sd8997) bluetooth SDIO devices
|
||||
Marvell 8897/8997 (sd8897/sd8997) bluetooth devices (SDIO or USB based)
|
||||
------
|
||||
The 8997 devices supports multiple interfaces. When used on SDIO interfaces,
|
||||
the btmrvl driver is used and when used on USB interface, the btusb driver is
|
||||
used.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be one of the following:
|
||||
* "marvell,sd8897-bt"
|
||||
* "marvell,sd8997-bt"
|
||||
* "marvell,sd8897-bt" (for SDIO)
|
||||
* "marvell,sd8997-bt" (for SDIO)
|
||||
* "usb1286,204e" (for USB)
|
||||
|
||||
Optional properties:
|
||||
|
||||
- marvell,cal-data: Calibration data downloaded to the device during
|
||||
initialization. This is an array of 28 values(u8).
|
||||
This is only applicable to SDIO devices.
|
||||
|
||||
- marvell,wakeup-pin: It represents wakeup pin number of the bluetooth chip.
|
||||
firmware will use the pin to wakeup host system (u16).
|
||||
|
@ -18,10 +23,15 @@ Optional properties:
|
|||
platform. The value will be configured to firmware. This
|
||||
is needed to work chip's sleep feature as expected (u16).
|
||||
- interrupt-parent: phandle of the parent interrupt controller
|
||||
- interrupts : interrupt pin number to the cpu. Driver will request an irq based
|
||||
on this interrupt number. During system suspend, the irq will be
|
||||
enabled so that the bluetooth chip can wakeup host platform under
|
||||
certain condition. During system resume, the irq will be disabled
|
||||
- interrupt-names: Used only for USB based devices (See below)
|
||||
- interrupts : specifies the interrupt pin number to the cpu. For SDIO, the
|
||||
driver will use the first interrupt specified in the interrupt
|
||||
array. For USB based devices, the driver will use the interrupt
|
||||
named "wakeup" from the interrupt-names and interrupt arrays.
|
||||
The driver will request an irq based on this interrupt number.
|
||||
During system suspend, the irq will be enabled so that the
|
||||
bluetooth chip can wakeup host platform under certain
|
||||
conditions. During system resume, the irq will be disabled
|
||||
to make sure unnecessary interrupt is not received.
|
||||
|
||||
Example:
|
||||
|
@ -29,7 +39,9 @@ Example:
|
|||
IRQ pin 119 is used as system wakeup source interrupt.
|
||||
wakeup pin 13 and gap 100ms are configured so that firmware can wakeup host
|
||||
using this device side pin and wakeup latency.
|
||||
calibration data is also available in below example.
|
||||
|
||||
Example for SDIO device follows (calibration data is also available in
|
||||
below example).
|
||||
|
||||
&mmc3 {
|
||||
status = "okay";
|
||||
|
@ -54,3 +66,21 @@ calibration data is also available in below example.
|
|||
marvell,wakeup-gap-ms = /bits/ 16 <0x64>;
|
||||
};
|
||||
};
|
||||
|
||||
Example for USB device:
|
||||
|
||||
&usb_host1_ohci {
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mvl_bt1: bt@1 {
|
||||
compatible = "usb1286,204e";
|
||||
reg = <1>;
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupt-names = "wakeup";
|
||||
interrupts = <119 IRQ_TYPE_LEVEL_LOW>;
|
||||
marvell,wakeup-pin = /bits/ 16 <0x0d>;
|
||||
marvell,wakeup-gap-ms = /bits/ 16 <0x64>;
|
||||
};
|
||||
};
|
|
@ -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.
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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_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_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_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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
|
|||
if (err == 0) {
|
||||
sock_recv_ts_and_drops(msg, sk, skb);
|
||||
|
||||
if (bt_sk(sk)->skb_msg_name)
|
||||
if (msg->msg_name && bt_sk(sk)->skb_msg_name)
|
||||
bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
|
||||
&msg->msg_namelen);
|
||||
}
|
||||
|
|
|
@ -4749,7 +4749,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
|
|||
case LE_ADV_SCAN_RSP:
|
||||
break;
|
||||
default:
|
||||
BT_ERR_RATELIMITED("Unknown advetising packet type: 0x%02x",
|
||||
BT_ERR_RATELIMITED("Unknown advertising packet type: 0x%02x",
|
||||
type);
|
||||
return;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче