summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/Kconfig3
-rw-r--r--drivers/bluetooth/bfusb.c6
-rw-r--r--drivers/bluetooth/bluecard_cs.c4
-rw-r--r--drivers/bluetooth/bpa10x.c2
-rw-r--r--drivers/bluetooth/bt3c_cs.c2
-rw-r--r--drivers/bluetooth/btbcm.c37
-rw-r--r--drivers/bluetooth/btintel.c2
-rw-r--r--drivers/bluetooth/btmrvl_main.c4
-rw-r--r--drivers/bluetooth/btqcomsmd.c2
-rw-r--r--drivers/bluetooth/btuart_cs.c2
-rw-r--r--drivers/bluetooth/btusb.c27
-rw-r--r--drivers/bluetooth/btwilink.c1
-rw-r--r--drivers/bluetooth/dtl1_cs.c4
-rw-r--r--drivers/bluetooth/hci_bcm.c23
-rw-r--r--drivers/bluetooth/hci_bcsp.c16
-rw-r--r--drivers/bluetooth/hci_h4.c2
-rw-r--r--drivers/bluetooth/hci_h5.c12
-rw-r--r--drivers/bluetooth/hci_intel.c27
-rw-r--r--drivers/bluetooth/hci_ldisc.c40
-rw-r--r--drivers/bluetooth/hci_ll.c27
-rw-r--r--drivers/bluetooth/hci_mrvl.c2
-rw-r--r--drivers/bluetooth/hci_nokia.c14
-rw-r--r--drivers/bluetooth/hci_qca.c4
-rw-r--r--drivers/bluetooth/hci_serdev.c4
-rw-r--r--drivers/bluetooth/hci_uart.h1
-rw-r--r--drivers/bluetooth/hci_vhci.c4
26 files changed, 193 insertions, 79 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 737d93ef27c5..35952a94875e 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -97,6 +97,7 @@ config BT_HCIUART_NOKIA
depends on BT_HCIUART
depends on BT_HCIUART_SERDEV
depends on PM
+ select BT_HCIUART_H4
help
Nokia H4+ is serial protocol for communication between Bluetooth
device and host. This protocol is required for Bluetooth devices
@@ -131,7 +132,7 @@ config BT_HCIUART_ATH3K
config BT_HCIUART_LL
bool "HCILL protocol support"
- depends on BT_HCIUART
+ depends on BT_HCIUART_SERDEV
help
HCILL (HCI Low Level) is a serial protocol for communication
between Bluetooth device and host. This protocol is required for
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 3bf4ec60e073..ab090a313a5f 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -335,7 +335,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
}
if (len > 0)
- memcpy(skb_put(data->reassembly, len), buf, len);
+ skb_put_data(data->reassembly, buf, len);
if (hdr & 0x08) {
hci_recv_frame(data->hdev, data->reassembly);
@@ -505,7 +505,7 @@ static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
buf[1] = 0x00;
buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;
- memcpy(skb_put(nskb, 3), buf, 3);
+ skb_put_data(nskb, buf, 3);
skb_copy_from_linear_data_offset(skb, sent, skb_put(nskb, size), size);
sent += size;
@@ -516,7 +516,7 @@ static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
if ((nskb->len % data->bulk_pkt_size) == 0) {
buf[0] = 0xdd;
buf[1] = 0x00;
- memcpy(skb_put(nskb, 2), buf, 2);
+ skb_put_data(nskb, buf, 2);
}
read_lock(&data->lock);
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 007c0a45f31b..d4b0b655dde6 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -448,7 +448,7 @@ static void bluecard_receive(struct bluecard_info *info,
} else {
- *skb_put(info->rx_skb, 1) = buf[i];
+ skb_put_u8(info->rx_skb, buf[i]);
info->rx_count--;
if (info->rx_count == 0) {
@@ -597,7 +597,7 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
break;
}
- memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
+ skb_put_data(skb, cmd, sizeof(cmd));
skb_queue_tail(&(info->txq), skb);
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index a9932fe57d92..48d10cb5c9a1 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -297,7 +297,7 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
return -ENOMEM;
/* Prepend skb with frame type */
- *skb_push(skb, 1) = hci_skb_pkt_type(skb);
+ *(u8 *)skb_push(skb, 1) = hci_skb_pkt_type(skb);
switch (hci_skb_pkt_type(skb)) {
case HCI_COMMAND_PKT:
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 8165ef2fe877..32dcac017395 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -282,7 +282,7 @@ static void bt3c_receive(struct bt3c_info *info)
__u8 x = inb(iobase + DATA_L);
- *skb_put(info->rx_skb, 1) = x;
+ skb_put_u8(info->rx_skb, x);
inb(iobase + DATA_H);
info->rx_count--;
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
index ba3dd2eafc09..9ab6cfbb831d 100644
--- a/drivers/bluetooth/btbcm.c
+++ b/drivers/bluetooth/btbcm.c
@@ -246,6 +246,27 @@ static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
return skb;
}
+static struct sk_buff *btbcm_read_controller_features(struct hci_dev *hdev)
+{
+ struct sk_buff *skb;
+
+ skb = __hci_cmd_sync(hdev, 0xfc6e, 0, NULL, HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ BT_ERR("%s: BCM: Read controller features failed (%ld)",
+ hdev->name, PTR_ERR(skb));
+ return skb;
+ }
+
+ if (skb->len != 9) {
+ BT_ERR("%s: BCM: Controller features length mismatch",
+ hdev->name);
+ kfree_skb(skb);
+ return ERR_PTR(-EIO);
+ }
+
+ return skb;
+}
+
static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
{
struct sk_buff *skb;
@@ -274,6 +295,7 @@ static const struct {
{ 0x410e, "BCM43341B0" }, /* 002.001.014 */
{ 0x4406, "BCM4324B3" }, /* 002.004.006 */
{ 0x610c, "BCM4354" }, /* 003.001.012 */
+ { 0x2209, "BCM43430A1" }, /* 001.002.009 */
{ }
};
@@ -417,6 +439,14 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
kfree_skb(skb);
+ /* Read Controller Features */
+ skb = btbcm_read_controller_features(hdev);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ BT_INFO("%s: BCM: features 0x%2.2x", hdev->name, skb->data[1]);
+ kfree_skb(skb);
+
/* Read Local Name */
skb = btbcm_read_local_name(hdev);
if (IS_ERR(skb))
@@ -540,6 +570,13 @@ int btbcm_setup_apple(struct hci_dev *hdev)
kfree_skb(skb);
}
+ /* Read Controller Features */
+ skb = btbcm_read_controller_features(hdev);
+ if (!IS_ERR(skb)) {
+ BT_INFO("%s: BCM: features 0x%2.2x", hdev->name, skb->data[1]);
+ kfree_skb(skb);
+ }
+
/* Read Local Name */
skb = btbcm_read_local_name(hdev);
if (!IS_ERR(skb)) {
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index fce154855718..d32e109bd5cb 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -575,3 +575,5 @@ MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("intel/ibt-11-5.sfi");
MODULE_FIRMWARE("intel/ibt-11-5.ddc");
+MODULE_FIRMWARE("intel/ibt-12-16.sfi");
+MODULE_FIRMWARE("intel/ibt-12-16.ddc");
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index fe850f0567cb..b280d466f05b 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -189,12 +189,12 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
return -ENOMEM;
}
- hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE);
+ hdr = skb_put(skb, HCI_COMMAND_HDR_SIZE);
hdr->opcode = cpu_to_le16(opcode);
hdr->plen = len;
if (len)
- memcpy(skb_put(skb, len), param, len);
+ skb_put_data(skb, param, len);
hci_skb_pkt_type(skb) = MRVL_VENDOR_PKT;
diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c
index ef730c173d4b..d00c4fdae924 100644
--- a/drivers/bluetooth/btqcomsmd.c
+++ b/drivers/bluetooth/btqcomsmd.c
@@ -43,7 +43,7 @@ static int btqcomsmd_recv(struct hci_dev *hdev, unsigned int type,
}
hci_skb_pkt_type(skb) = type;
- memcpy(skb_put(skb, count), data, count);
+ skb_put_data(skb, data, count);
return hci_recv_frame(hdev, skb);
}
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 9624b29f8349..7df79bb12350 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -233,7 +233,7 @@ static void btuart_receive(struct btuart_info *info)
} else {
- *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
+ skb_put_u8(info->rx_skb, inb(iobase + UART_RX));
info->rx_count--;
if (info->rx_count == 0) {
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 7fa373b428f8..fa24d693af24 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -266,6 +266,7 @@ static const struct usb_device_id blacklist_table[] = {
{ 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(0x0489, 0xe0a2), .driver_info = BTUSB_QCA_ROME },
{ USB_DEVICE(0x04ca, 0x3011), .driver_info = BTUSB_QCA_ROME },
/* Broadcom BCM2035 */
@@ -336,6 +337,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
{ USB_DEVICE(0x8087, 0x0a2b), .driver_info = BTUSB_INTEL_NEW },
{ USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL },
+ { USB_DEVICE(0x8087, 0x0aaa), .driver_info = BTUSB_INTEL_NEW },
/* Other Intel Bluetooth devices */
{ USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01),
@@ -476,7 +478,7 @@ static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)
}
len = min_t(uint, hci_skb_expect(skb), count);
- memcpy(skb_put(skb, len), buffer, len);
+ skb_put_data(skb, buffer, len);
count -= len;
buffer += len;
@@ -531,7 +533,7 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
}
len = min_t(uint, hci_skb_expect(skb), count);
- memcpy(skb_put(skb, len), buffer, len);
+ skb_put_data(skb, buffer, len);
count -= len;
buffer += len;
@@ -588,7 +590,7 @@ static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
}
len = min_t(uint, hci_skb_expect(skb), count);
- memcpy(skb_put(skb, len), buffer, len);
+ skb_put_data(skb, buffer, len);
count -= len;
buffer += len;
@@ -932,8 +934,8 @@ static void btusb_diag_complete(struct urb *urb)
skb = bt_skb_alloc(urb->actual_length, GFP_ATOMIC);
if (skb) {
- memcpy(skb_put(skb, urb->actual_length),
- urb->transfer_buffer, urb->actual_length);
+ skb_put_data(skb, urb->transfer_buffer,
+ urb->actual_length);
hci_recv_diag(hdev, skb);
}
} else if (urb->status == -ENOENT) {
@@ -1834,15 +1836,15 @@ static int inject_cmd_complete(struct hci_dev *hdev, __u16 opcode)
if (!skb)
return -ENOMEM;
- hdr = (struct hci_event_hdr *)skb_put(skb, sizeof(*hdr));
+ hdr = skb_put(skb, sizeof(*hdr));
hdr->evt = HCI_EV_CMD_COMPLETE;
hdr->plen = sizeof(*evt) + 1;
- evt = (struct hci_ev_cmd_complete *)skb_put(skb, sizeof(*evt));
+ evt = skb_put(skb, sizeof(*evt));
evt->ncmd = 0x01;
evt->opcode = cpu_to_le16(opcode);
- *skb_put(skb, 1) = 0x00;
+ skb_put_u8(skb, 0x00);
hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
@@ -2036,6 +2038,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
switch (ver.hw_variant) {
case 0x0b: /* SfP */
case 0x0c: /* WsP */
+ case 0x11: /* JfP */
case 0x12: /* ThP */
break;
default:
@@ -2138,6 +2141,8 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
* Currently the supported hardware variants are:
* 11 (0x0b) for iBT3.0 (LnP/SfP)
* 12 (0x0c) for iBT3.5 (WsP)
+ * 17 (0x11) for iBT3.5 (JfP)
+ * 18 (0x12) for iBT3.5 (ThP)
*/
snprintf(fwname, sizeof(fwname), "intel/ibt-%u-%u.sfi",
le16_to_cpu(ver.hw_variant),
@@ -2390,7 +2395,7 @@ static int marvell_config_oob_wake(struct hci_dev *hdev)
return -ENOMEM;
}
- memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
+ skb_put_data(skb, cmd, sizeof(cmd));
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
ret = btusb_send_frame(hdev, skb);
@@ -2762,8 +2767,8 @@ static struct urb *alloc_diag_urb(struct hci_dev *hdev, bool enable)
return ERR_PTR(-ENOMEM);
}
- *skb_put(skb, 1) = 0xf0;
- *skb_put(skb, 1) = enable;
+ skb_put_u8(skb, 0xf0);
+ skb_put_u8(skb, enable);
pipe = usb_sndbulkpipe(data->udev, data->diag_tx_ep->bEndpointAddress);
diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c
index b6bb58c41df5..85a3978b064f 100644
--- a/drivers/bluetooth/btwilink.c
+++ b/drivers/bluetooth/btwilink.c
@@ -262,7 +262,6 @@ static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
pkt_type = hci_skb_pkt_type(skb);
len = hst->st_write(skb);
if (len < 0) {
- kfree_skb(skb);
BT_ERR("ST write failed (%ld)", len);
/* Try Again, would only fail if UART has gone bad */
return -EAGAIN;
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 6317c6f323bf..2adfe4fade76 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -226,7 +226,7 @@ static void dtl1_receive(struct dtl1_info *info)
}
}
- *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
+ skb_put_u8(info->rx_skb, inb(iobase + UART_RX));
nsh = (struct nsh *)info->rx_skb->data;
info->rx_count--;
@@ -414,7 +414,7 @@ static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
skb_reserve(s, NSHL);
skb_copy_from_linear_data(skb, skb_put(s, skb->len), skb->len);
if (skb->len & 0x0001)
- *skb_put(s, 1) = 0; /* PAD */
+ skb_put_u8(s, 0); /* PAD */
/* Prepend skb with Nokia frame header and queue */
memcpy(skb_push(s, NSHL), &nsh, NSHL);
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index f87bfdfee4ff..6a662d0161b4 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -262,9 +262,9 @@ static int bcm_set_diag(struct hci_dev *hdev, bool enable)
if (!skb)
return -ENOMEM;
- *skb_put(skb, 1) = BCM_LM_DIAG_PKT;
- *skb_put(skb, 1) = 0xf0;
- *skb_put(skb, 1) = enable;
+ skb_put_u8(skb, BCM_LM_DIAG_PKT);
+ skb_put_u8(skb, 0xf0);
+ skb_put_u8(skb, enable);
skb_queue_tail(&bcm->txq, skb);
hci_uart_tx_wakeup(hu);
@@ -419,8 +419,7 @@ finalize:
if (err)
return err;
- err = bcm_request_irq(bcm);
- if (!err)
+ if (!bcm_request_irq(bcm))
err = bcm_setup_sleep(hu);
return err;
@@ -657,6 +656,15 @@ static const struct dmi_system_id bcm_wrong_irq_dmi_table[] = {
},
.driver_data = &acpi_active_low,
},
+ {
+ .ident = "Asus T100CHI",
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR,
+ "ASUSTeK COMPUTER INC."),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100CHI"),
+ },
+ .driver_data = &acpi_active_low,
+ },
{ /* Handle ThinkPad 8 tablets with BCM2E55 chipset ACPI ID */
.ident = "Lenovo ThinkPad 8",
.matches = {
@@ -762,8 +770,7 @@ static int bcm_acpi_probe(struct bcm_device *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);
+ ret = devm_acpi_dev_add_driver_gpios(&pdev->dev, gpio_mapping);
if (ret)
return ret;
@@ -834,8 +841,6 @@ static int bcm_remove(struct platform_device *pdev)
list_del(&dev->list);
mutex_unlock(&bcm_device_lock);
- acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));
-
dev_info(&pdev->dev, "%s device unregistered.\n", dev->name);
return 0;
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 910ec968f022..d880f4e33c75 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -125,7 +125,7 @@ static void bcsp_slip_msgdelim(struct sk_buff *skb)
{
const char pkt_delim = 0xc0;
- memcpy(skb_put(skb, 1), &pkt_delim, 1);
+ skb_put_data(skb, &pkt_delim, 1);
}
static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
@@ -135,13 +135,13 @@ static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
switch (c) {
case 0xc0:
- memcpy(skb_put(skb, 2), &esc_c0, 2);
+ skb_put_data(skb, &esc_c0, 2);
break;
case 0xdb:
- memcpy(skb_put(skb, 2), &esc_db, 2);
+ skb_put_data(skb, &esc_db, 2);
break;
default:
- memcpy(skb_put(skb, 1), &c, 1);
+ skb_put_data(skb, &c, 1);
}
}
@@ -423,7 +423,7 @@ static void bcsp_handle_le_pkt(struct hci_uart *hu)
BT_DBG("Found a LE conf pkt");
if (!nskb)
return;
- memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
+ skb_put_data(nskb, conf_rsp_pkt, 4);
hci_skb_pkt_type(nskb) = BCSP_LE_PKT;
skb_queue_head(&bcsp->unrel, nskb);
@@ -447,7 +447,7 @@ static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char
bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
break;
default:
- memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
+ skb_put_data(bcsp->rx_skb, &byte, 1);
if ((bcsp->rx_skb->data[0] & 0x40) != 0 &&
bcsp->rx_state != BCSP_W4_CRC)
bcsp_crc_update(&bcsp->message_crc, byte);
@@ -458,7 +458,7 @@ static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char
case BCSP_ESCSTATE_ESC:
switch (byte) {
case 0xdc:
- memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
+ skb_put_data(bcsp->rx_skb, &c0, 1);
if ((bcsp->rx_skb->data[0] & 0x40) != 0 &&
bcsp->rx_state != BCSP_W4_CRC)
bcsp_crc_update(&bcsp->message_crc, 0xc0);
@@ -467,7 +467,7 @@ static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char
break;
case 0xdd:
- memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
+ skb_put_data(bcsp->rx_skb, &db, 1);
if ((bcsp->rx_skb->data[0] & 0x40) != 0 &&
bcsp->rx_state != BCSP_W4_CRC)
bcsp_crc_update(&bcsp->message_crc, 0xdb);
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 82e5a32b87a4..4e328d7d47bb 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -209,7 +209,7 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
}
len = min_t(uint, hci_skb_expect(skb) - skb->len, count);
- memcpy(skb_put(skb, len), buffer, len);
+ skb_put_data(skb, buffer, len);
count -= len;
buffer += len;
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 90d0456b6744..c0e4e26dc30d 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -109,7 +109,7 @@ static void h5_link_control(struct hci_uart *hu, const void *data, size_t len)
hci_skb_pkt_type(nskb) = HCI_3WIRE_LINK_PKT;
- memcpy(skb_put(nskb, len), data, len);
+ skb_put_data(nskb, data, len);
skb_queue_tail(&h5->unrel, nskb);
}
@@ -487,7 +487,7 @@ static void h5_unslip_one_byte(struct h5 *h5, unsigned char c)
}
}
- memcpy(skb_put(h5->rx_skb, 1), byte, 1);
+ skb_put_data(h5->rx_skb, byte, 1);
h5->rx_pending--;
BT_DBG("unsliped 0x%02hhx, rx_pending %zu", *byte, h5->rx_pending);
@@ -579,7 +579,7 @@ static void h5_slip_delim(struct sk_buff *skb)
{
const char delim = SLIP_DELIMITER;
- memcpy(skb_put(skb, 1), &delim, 1);
+ skb_put_data(skb, &delim, 1);
}
static void h5_slip_one_byte(struct sk_buff *skb, u8 c)
@@ -589,13 +589,13 @@ static void h5_slip_one_byte(struct sk_buff *skb, u8 c)
switch (c) {
case SLIP_DELIMITER:
- memcpy(skb_put(skb, 2), &esc_delim, 2);
+ skb_put_data(skb, &esc_delim, 2);
break;
case SLIP_ESC:
- memcpy(skb_put(skb, 2), &esc_esc, 2);
+ skb_put_data(skb, &esc_esc, 2);
break;
default:
- memcpy(skb_put(skb, 1), &c, 1);
+ skb_put_data(skb, &c, 1);
}
}
diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c
index fa5099986f1b..aad07e40ea4f 100644
--- a/drivers/bluetooth/hci_intel.c
+++ b/drivers/bluetooth/hci_intel.c
@@ -185,7 +185,7 @@ static int intel_lpm_suspend(struct hci_uart *hu)
return -ENOMEM;
}
- memcpy(skb_put(skb, sizeof(suspend)), suspend, sizeof(suspend));
+ skb_put_data(skb, suspend, sizeof(suspend));
hci_skb_pkt_type(skb) = HCI_LPM_PKT;
set_bit(STATE_LPM_TRANSACTION, &intel->flags);
@@ -270,8 +270,7 @@ static int intel_lpm_host_wake(struct hci_uart *hu)
return -ENOMEM;
}
- memcpy(skb_put(skb, sizeof(lpm_resume_ack)), lpm_resume_ack,
- sizeof(lpm_resume_ack));
+ skb_put_data(skb, lpm_resume_ack, sizeof(lpm_resume_ack));
hci_skb_pkt_type(skb) = HCI_LPM_PKT;
/* LPM flow is a priority, enqueue packet at list head */
@@ -463,15 +462,15 @@ static int inject_cmd_complete(struct hci_dev *hdev, __u16 opcode)
if (!skb)
return -ENOMEM;
- hdr = (struct hci_event_hdr *)skb_put(skb, sizeof(*hdr));
+ hdr = skb_put(skb, sizeof(*hdr));
hdr->evt = HCI_EV_CMD_COMPLETE;
hdr->plen = sizeof(*evt) + 1;
- evt = (struct hci_ev_cmd_complete *)skb_put(skb, sizeof(*evt));
+ evt = skb_put(skb, sizeof(*evt));
evt->ncmd = 0x01;
evt->opcode = cpu_to_le16(opcode);
- *skb_put(skb, 1) = 0x00;
+ skb_put_u8(skb, 0x00);
hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
@@ -522,7 +521,7 @@ static int intel_set_baudrate(struct hci_uart *hu, unsigned int speed)
return -ENOMEM;
}
- memcpy(skb_put(skb, sizeof(speed_cmd)), speed_cmd, sizeof(speed_cmd));
+ skb_put_data(skb, speed_cmd, sizeof(speed_cmd));
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
hci_uart_set_flow_control(hu, true);
@@ -1205,9 +1204,19 @@ static const struct dev_pm_ops intel_pm_ops = {
SET_RUNTIME_PM_OPS(intel_suspend_device, intel_resume_device, NULL)
};
+static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
+static const struct acpi_gpio_params host_wake_gpios = { 1, 0, false };
+
+static const struct acpi_gpio_mapping acpi_hci_intel_gpios[] = {
+ { "reset-gpios", &reset_gpios, 1 },
+ { "host-wake-gpios", &host_wake_gpios, 1 },
+ { },
+};
+
static int intel_probe(struct platform_device *pdev)
{
struct intel_device *idev;
+ int ret;
idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
if (!idev)
@@ -1217,6 +1226,10 @@ static int intel_probe(struct platform_device *pdev)
idev->pdev = pdev;
+ ret = devm_acpi_dev_add_driver_gpios(&pdev->dev, acpi_hci_intel_gpios);
+ if (ret)
+ dev_dbg(&pdev->dev, "Unable to add GPIO mapping table\n");
+
idev->reset = devm_gpiod_get(&pdev->dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(idev->reset)) {
dev_err(&pdev->dev, "Unable to retrieve gpio\n");
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 2edd30556956..8397b716fa65 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -114,8 +114,12 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
struct sk_buff *skb = hu->tx_skb;
if (!skb) {
+ read_lock(&hu->proto_lock);
+
if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
skb = hu->proto->dequeue(hu);
+
+ read_unlock(&hu->proto_lock);
} else {
hu->tx_skb = NULL;
}
@@ -125,18 +129,23 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
int hci_uart_tx_wakeup(struct hci_uart *hu)
{
+ read_lock(&hu->proto_lock);
+
if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
- return 0;
+ goto no_schedule;
if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
- return 0;
+ goto no_schedule;
}
BT_DBG("");
schedule_work(&hu->write_work);
+no_schedule:
+ read_unlock(&hu->proto_lock);
+
return 0;
}
EXPORT_SYMBOL_GPL(hci_uart_tx_wakeup);
@@ -237,9 +246,13 @@ static int hci_uart_flush(struct hci_dev *hdev)
tty_ldisc_flush(tty);
tty_driver_flush_buffer(tty);
+ read_lock(&hu->proto_lock);
+
if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
hu->proto->flush(hu);
+ read_unlock(&hu->proto_lock);
+
return 0;
}
@@ -261,10 +274,15 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s: type %d len %d", hdev->name, hci_skb_pkt_type(skb),
skb->len);
- if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
+ read_lock(&hu->proto_lock);
+
+ if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
+ read_unlock(&hu->proto_lock);
return -EUNATCH;
+ }
hu->proto->enqueue(hu, skb);
+ read_unlock(&hu->proto_lock);
hci_uart_tx_wakeup(hu);
@@ -460,6 +478,8 @@ static int hci_uart_tty_open(struct tty_struct *tty)
INIT_WORK(&hu->init_ready, hci_uart_init_work);
INIT_WORK(&hu->write_work, hci_uart_write_work);
+ rwlock_init(&hu->proto_lock);
+
/* Flush any pending characters in the driver */
tty_driver_flush_buffer(tty);
@@ -475,6 +495,7 @@ static void hci_uart_tty_close(struct tty_struct *tty)
{
struct hci_uart *hu = tty->disc_data;
struct hci_dev *hdev;
+ unsigned long flags;
BT_DBG("tty %p", tty);
@@ -490,7 +511,11 @@ static void hci_uart_tty_close(struct tty_struct *tty)
cancel_work_sync(&hu->write_work);
- if (test_and_clear_bit(HCI_UART_PROTO_READY, &hu->flags)) {
+ if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
+ write_lock_irqsave(&hu->proto_lock, flags);
+ clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+ write_unlock_irqrestore(&hu->proto_lock, flags);
+
if (hdev) {
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
hci_unregister_dev(hdev);
@@ -549,13 +574,18 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data,
if (!hu || tty != hu->tty)
return;
- if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
+ read_lock(&hu->proto_lock);
+
+ if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
+ read_unlock(&hu->proto_lock);
return;
+ }
/* It does not need a lock here as it is already protected by a mutex in
* tty caller
*/
hu->proto->recv(hu, data, count);
+ read_unlock(&hu->proto_lock);
if (hu->hdev)
hu->hdev->stat.byte_rx += count;
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index adc444f309a3..c982943f0747 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -48,6 +48,7 @@
#include <linux/serdev.h>
#include <linux/skbuff.h>
#include <linux/ti_wilink_st.h>
+#include <linux/clk.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -84,6 +85,7 @@ struct ll_device {
struct hci_uart hu;
struct serdev_device *serdev;
struct gpio_desc *enable_gpio;
+ struct clk *ext_clk;
};
struct ll_struct {
@@ -118,7 +120,7 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
}
/* prepare packet */
- hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
+ hcill_packet = skb_put(skb, 1);
hcill_packet->cmd = cmd;
/* send packet */
@@ -146,8 +148,12 @@ static int ll_open(struct hci_uart *hu)
hu->priv = ll;
- if (hu->serdev)
+ if (hu->serdev) {
+ struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
serdev_device_open(hu->serdev);
+ if (!IS_ERR(lldev->ext_clk))
+ clk_prepare_enable(lldev->ext_clk);
+ }
return 0;
}
@@ -181,6 +187,8 @@ static int ll_close(struct hci_uart *hu)
struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
gpiod_set_value_cansleep(lldev->enable_gpio, 0);
+ clk_disable_unprepare(lldev->ext_clk);
+
serdev_device_close(hu->serdev);
}
@@ -405,7 +413,7 @@ static int ll_recv(struct hci_uart *hu, const void *data, int count)
while (count) {
if (ll->rx_count) {
len = min_t(unsigned int, ll->rx_count, count);
- memcpy(skb_put(ll->rx_skb, len), ptr, len);
+ skb_put_data(ll->rx_skb, ptr, len);
ll->rx_count -= len; count -= len; ptr += len;
if (ll->rx_count)
@@ -624,6 +632,7 @@ static int download_firmware(struct ll_device *lldev)
skb = __hci_cmd_sync(lldev->hu.hdev, cmd->opcode, cmd->plen, &cmd->speed, HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
bt_dev_err(lldev->hu.hdev, "send command failed\n");
+ err = PTR_ERR(skb);
goto out_rel_fw;
}
kfree_skb(skb);
@@ -720,6 +729,10 @@ static int hci_ti_probe(struct serdev_device *serdev)
if (IS_ERR(lldev->enable_gpio))
return PTR_ERR(lldev->enable_gpio);
+ lldev->ext_clk = devm_clk_get(&serdev->dev, "ext_clock");
+ if (IS_ERR(lldev->ext_clk) && PTR_ERR(lldev->ext_clk) != -ENOENT)
+ return PTR_ERR(lldev->ext_clk);
+
of_property_read_u32(serdev->dev.of_node, "max-speed", &max_speed);
hci_uart_set_speeds(hu, 115200, max_speed);
@@ -740,6 +753,14 @@ static void hci_ti_remove(struct serdev_device *serdev)
}
static const struct of_device_id hci_ti_of_match[] = {
+ { .compatible = "ti,wl1271-st" },
+ { .compatible = "ti,wl1273-st" },
+ { .compatible = "ti,wl1281-st" },
+ { .compatible = "ti,wl1283-st" },
+ { .compatible = "ti,wl1285-st" },
+ { .compatible = "ti,wl1801-st" },
+ { .compatible = "ti,wl1805-st" },
+ { .compatible = "ti,wl1807-st" },
{ .compatible = "ti,wl1831-st" },
{ .compatible = "ti,wl1835-st" },
{ .compatible = "ti,wl1837-st" },
diff --git a/drivers/bluetooth/hci_mrvl.c b/drivers/bluetooth/hci_mrvl.c
index bbc4b39b1dbf..ffb00669346f 100644
--- a/drivers/bluetooth/hci_mrvl.c
+++ b/drivers/bluetooth/hci_mrvl.c
@@ -328,7 +328,7 @@ static int mrvl_load_firmware(struct hci_dev *hdev, const char *name)
}
bt_cb(skb)->pkt_type = MRVL_RAW_DATA;
- memcpy(skb_put(skb, mrvl->tx_len), fw_ptr, mrvl->tx_len);
+ skb_put_data(skb, fw_ptr, mrvl->tx_len);
fw_ptr += mrvl->tx_len;
set_bit(STATE_FW_REQ_PENDING, &mrvl->flags);
diff --git a/drivers/bluetooth/hci_nokia.c b/drivers/bluetooth/hci_nokia.c
index a7d687d8d456..181a15b549e5 100644
--- a/drivers/bluetooth/hci_nokia.c
+++ b/drivers/bluetooth/hci_nokia.c
@@ -246,9 +246,9 @@ static int nokia_send_alive_packet(struct hci_uart *hu)
hci_skb_pkt_type(skb) = HCI_NOKIA_ALIVE_PKT;
memset(skb->data, 0x00, len);
- hdr = (struct hci_nokia_alive_hdr *)skb_put(skb, sizeof(*hdr));
+ hdr = skb_put(skb, sizeof(*hdr));
hdr->dlen = sizeof(*pkt);
- pkt = (struct hci_nokia_alive_pkt *)skb_put(skb, sizeof(*pkt));
+ pkt = skb_put(skb, sizeof(*pkt));
pkt->mid = NOKIA_ALIVE_REQ;
nokia_enqueue(hu, skb);
@@ -285,10 +285,10 @@ static int nokia_send_negotiation(struct hci_uart *hu)
hci_skb_pkt_type(skb) = HCI_NOKIA_NEG_PKT;
- neg_hdr = (struct hci_nokia_neg_hdr *)skb_put(skb, sizeof(*neg_hdr));
+ neg_hdr = skb_put(skb, sizeof(*neg_hdr));
neg_hdr->dlen = sizeof(*neg_cmd);
- neg_cmd = (struct hci_nokia_neg_cmd *)skb_put(skb, sizeof(*neg_cmd));
+ neg_cmd = skb_put(skb, sizeof(*neg_cmd));
neg_cmd->ack = NOKIA_NEG_REQ;
neg_cmd->baud = cpu_to_le16(baud);
neg_cmd->unused1 = 0x0000;
@@ -532,7 +532,7 @@ static int nokia_enqueue(struct hci_uart *hu, struct sk_buff *skb)
err = skb_pad(skb, 1);
if (err)
return err;
- *skb_put(skb, 1) = 0x00;
+ skb_put_u8(skb, 0x00);
}
skb_queue_tail(&btdev->txq, skb);
@@ -557,7 +557,7 @@ static int nokia_recv_negotiation_packet(struct hci_dev *hdev,
goto finish_neg;
}
- evt = (struct hci_nokia_neg_evt *)skb_pull(skb, sizeof(*hdr));
+ evt = skb_pull(skb, sizeof(*hdr));
if (evt->ack != NOKIA_NEG_ACK) {
dev_err(dev, "Negotiation received: wrong reply");
@@ -595,7 +595,7 @@ static int nokia_recv_alive_packet(struct hci_dev *hdev, struct sk_buff *skb)
goto finish_alive;
}
- pkt = (struct hci_nokia_alive_pkt *)skb_pull(skb, sizeof(*hdr));
+ pkt = skb_pull(skb, sizeof(*hdr));
if (pkt->mid != NOKIA_ALIVE_RESP) {
dev_err(dev, "Alive received: invalid response: 0x%02x!",
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index f242dfd0c2e2..392f412b4575 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -215,7 +215,7 @@ static int send_hci_ibs_cmd(u8 cmd, struct hci_uart *hu)
}
/* Assign HCI_IBS type */
- *skb_put(skb, 1) = cmd;
+ skb_put_u8(skb, cmd);
skb_queue_tail(&qca->txq, skb);
@@ -869,7 +869,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
}
/* Assign commands to change baudrate and packet type. */
- memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
+ skb_put_data(skb, cmd, sizeof(cmd));
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
skb_queue_tail(&qca->txq, skb);
diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
index 7de0edc0ff8c..aea930101dd2 100644
--- a/drivers/bluetooth/hci_serdev.c
+++ b/drivers/bluetooth/hci_serdev.c
@@ -31,7 +31,7 @@
#include "hci_uart.h"
-struct serdev_device_ops hci_serdev_client_ops;
+static struct serdev_device_ops hci_serdev_client_ops;
static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
{
@@ -268,7 +268,7 @@ static int hci_uart_receive_buf(struct serdev_device *serdev, const u8 *data,
return count;
}
-struct serdev_device_ops hci_serdev_client_ops = {
+static struct serdev_device_ops hci_serdev_client_ops = {
.receive_buf = hci_uart_receive_buf,
.write_wakeup = hci_uart_write_wakeup,
};
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index 2b05e557fad0..c6e9e1cf63f8 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -87,6 +87,7 @@ struct hci_uart {
struct work_struct write_work;
const struct hci_uart_proto *proto;
+ rwlock_t proto_lock; /* Stop work for proto close */
void *priv;
struct sk_buff *tx_skb;
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 233e850fdac7..e6f6dbc04131 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -146,8 +146,8 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
hci_skb_pkt_type(skb) = HCI_VENDOR_PKT;
- *skb_put(skb, 1) = 0xff;
- *skb_put(skb, 1) = opcode;
+ skb_put_u8(skb, 0xff);
+ skb_put_u8(skb, opcode);
put_unaligned_le16(hdev->id, skb_put(skb, 2));
skb_queue_tail(&data->readq, skb);