diff options
author | David S. Miller <davem@davemloft.net> | 2015-03-31 12:45:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-31 12:45:58 -0400 |
commit | 89a3f3c55ba54e08968b12a5f8e7d1787a0bbb4a (patch) | |
tree | d5f5308662279892195231e2313f9d47dc1bb4f5 /drivers | |
parent | 32eaf120e66b1763626ed564adf1e42e69da82f4 (diff) | |
parent | a7a484bfca218f9671a3e3bc98851eab6b628310 (diff) |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says:
====================
pull request: bluetooth-next 2015-03-27
Here's another set of Bluetooth & 802.15.4 patches for 4.1:
- New API to control LE advertising data (i.e. peripheral role)
- mac802154 & at86rf230 cleanups
- Support for toggling quirks from debugfs (useful for testing)
- Memory leak fix for LE scanning
- Extra version info reading support for Broadcom controllers
Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/bluetooth/btusb.c | 57 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 11 | ||||
-rw-r--r-- | drivers/bluetooth/hci_uart.h | 1 | ||||
-rw-r--r-- | drivers/net/ieee802154/at86rf230.c | 10 |
4 files changed, 69 insertions, 10 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 708b6574d805..9bf4d6ae6c6b 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -24,6 +24,7 @@ #include <linux/module.h> #include <linux/usb.h> #include <linux/firmware.h> +#include <asm/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> @@ -53,6 +54,7 @@ static struct usb_driver btusb_driver; #define BTUSB_INTEL_NEW 0x2000 #define BTUSB_AMP 0x4000 #define BTUSB_QCA_ROME 0x8000 +#define BTUSB_BCM_APPLE 0x10000 static const struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ @@ -62,7 +64,8 @@ static const struct usb_device_id btusb_table[] = { { USB_DEVICE_INFO(0xe0, 0x01, 0x04), .driver_info = BTUSB_AMP }, /* Apple-specific (Broadcom) devices */ - { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) }, + { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01), + .driver_info = BTUSB_BCM_APPLE }, /* MediaTek MT76x0E */ { USB_DEVICE(0x0e8d, 0x763f) }, @@ -2458,6 +2461,25 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev) subver = le16_to_cpu(ver->lmp_subver); kfree_skb(skb); + /* Read Verbose Config Version Info */ + skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + ret = PTR_ERR(skb); + BT_ERR("%s: BCM: Read Verbose Version failed (%ld)", + hdev->name, ret); + return ret; + } + + if (skb->len != 7) { + BT_ERR("%s: BCM: Read Verbose Version event length mismatch", + hdev->name); + kfree_skb(skb); + return -EIO; + } + + BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]); + kfree_skb(skb); + for (i = 0; bcm_subver_table[i].name; i++) { if (subver == bcm_subver_table[i].subver) { hw_name = bcm_subver_table[i].name; @@ -2615,6 +2637,34 @@ static int btusb_set_bdaddr_bcm(struct hci_dev *hdev, const bdaddr_t *bdaddr) return 0; } +static int btusb_setup_bcm_apple(struct hci_dev *hdev) +{ + struct sk_buff *skb; + int err; + + /* Read Verbose Config Version Info */ + skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + BT_ERR("%s: BCM: Read Verbose Version failed (%d)", + hdev->name, err); + return err; + } + + if (skb->len != 7) { + BT_ERR("%s: BCM: Read Verbose Version event length mismatch", + hdev->name); + kfree_skb(skb); + return -EIO; + } + + BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, skb->data[1], + get_unaligned_le16(skb->data + 5)); + kfree_skb(skb); + + return 0; +} + static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev, const bdaddr_t *bdaddr) { @@ -3014,6 +3064,11 @@ static int btusb_probe(struct usb_interface *intf, set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); } + if (id->driver_info & BTUSB_BCM_APPLE) { + hdev->setup = btusb_setup_bcm_apple; + set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); + } + if (id->driver_info & BTUSB_INTEL) { hdev->setup = btusb_setup_intel; hdev->shutdown = btusb_shutdown_intel; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index dc487b5d1156..48a0c250d5b8 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -261,6 +261,16 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) return 0; } +static int hci_uart_setup(struct hci_dev *hdev) +{ + struct hci_uart *hu = hci_get_drvdata(hdev); + + if (hu->proto->setup) + return hu->proto->setup(hu); + + return 0; +} + /* ------ LDISC part ------ */ /* hci_uart_tty_open * @@ -426,6 +436,7 @@ static int hci_uart_register_dev(struct hci_uart *hu) hdev->close = hci_uart_close; hdev->flush = hci_uart_flush; hdev->send = hci_uart_send_frame; + hdev->setup = hci_uart_setup; SET_HCIDEV_DEV(hdev, hu->tty->dev); if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags)) diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index 247488edcbf9..074ed29092b4 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -59,6 +59,7 @@ struct hci_uart_proto { int (*flush)(struct hci_uart *hu); int (*recv)(struct hci_uart *hu, void *data, int len); int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb); + int (*setup)(struct hci_uart *hu); struct sk_buff *(*dequeue)(struct hci_uart *hu); }; diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index cc5efa149da1..5ad46f7f514f 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -25,7 +25,6 @@ #include <linux/irq.h> #include <linux/gpio.h> #include <linux/delay.h> -#include <linux/spinlock.h> #include <linux/spi/spi.h> #include <linux/spi/at86rf230.h> #include <linux/regmap.h> @@ -96,8 +95,6 @@ struct at86rf230_local { unsigned long cal_timeout; s8 max_frame_retries; bool is_tx; - /* spinlock for is_tx protection */ - spinlock_t lock; u8 tx_retry; struct sk_buff *tx_skb; struct at86rf230_state_change tx; @@ -460,6 +457,7 @@ at86rf230_async_error_recover(void *context) struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; + lp->is_tx = 0; at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, NULL, false); ieee802154_wake_queue(lp->hw); } @@ -878,10 +876,8 @@ at86rf230_rx_trac_check(void *context) static void at86rf230_irq_trx_end(struct at86rf230_local *lp) { - spin_lock(&lp->lock); if (lp->is_tx) { lp->is_tx = 0; - spin_unlock(&lp->lock); if (lp->tx_aret) at86rf230_async_state_change(lp, &lp->irq, @@ -894,7 +890,6 @@ at86rf230_irq_trx_end(struct at86rf230_local *lp) at86rf230_tx_complete, true); } else { - spin_unlock(&lp->lock); at86rf230_async_read_reg(lp, RG_TRX_STATE, &lp->irq, at86rf230_rx_trac_check, true); } @@ -964,9 +959,7 @@ at86rf230_write_frame(void *context) u8 *buf = ctx->buf; int rc; - spin_lock(&lp->lock); lp->is_tx = 1; - spin_unlock(&lp->lock); buf[0] = CMD_FB | CMD_WRITE; buf[1] = skb->len + 2; @@ -1698,7 +1691,6 @@ static int at86rf230_probe(struct spi_device *spi) if (rc < 0) goto free_dev; - spin_lock_init(&lp->lock); init_completion(&lp->state_complete); spi_set_drvdata(spi, lp); |