aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-04-30 11:56:43 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-04-30 11:56:43 -0400
commit0006433a5be9e0e155ad493e33c6e9bf3868a87f (patch)
tree3993166ba48d5c6259c04c836c5b4bd5f4643b85 /drivers/bluetooth
parentbb0f8609ba9a41aa7a24109926a0f540dc2a7c6d (diff)
parent22e70786413ed05950207eda7be420c280b776d7 (diff)
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/btmrvl_drv.h4
-rw-r--r--drivers/bluetooth/btmrvl_main.c19
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c103
-rw-r--r--drivers/bluetooth/btmrvl_sdio.h3
-rw-r--r--drivers/bluetooth/hci_h4.c7
5 files changed, 106 insertions, 30 deletions
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
index 7399303d7d99..dc79f88f8717 100644
--- a/drivers/bluetooth/btmrvl_drv.h
+++ b/drivers/bluetooth/btmrvl_drv.h
@@ -59,6 +59,8 @@ struct btmrvl_device {
59}; 59};
60 60
61struct btmrvl_adapter { 61struct btmrvl_adapter {
62 void *hw_regs_buf;
63 u8 *hw_regs;
62 u32 int_count; 64 u32 int_count;
63 struct sk_buff_head tx_queue; 65 struct sk_buff_head tx_queue;
64 u8 psmode; 66 u8 psmode;
@@ -140,7 +142,7 @@ void btmrvl_interrupt(struct btmrvl_private *priv);
140bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); 142bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
141int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); 143int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
142 144
143int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); 145int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd);
144int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv); 146int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
145int btmrvl_enable_ps(struct btmrvl_private *priv); 147int btmrvl_enable_ps(struct btmrvl_private *priv);
146int btmrvl_prepare_command(struct btmrvl_private *priv); 148int btmrvl_prepare_command(struct btmrvl_private *priv);
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 2c4997ce2484..e9dbddb0b8f1 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -24,6 +24,7 @@
24#include <net/bluetooth/hci_core.h> 24#include <net/bluetooth/hci_core.h>
25 25
26#include "btmrvl_drv.h" 26#include "btmrvl_drv.h"
27#include "btmrvl_sdio.h"
27 28
28#define VERSION "1.0" 29#define VERSION "1.0"
29 30
@@ -201,7 +202,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
201 return 0; 202 return 0;
202} 203}
203 204
204int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd) 205int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd)
205{ 206{
206 int ret; 207 int ret;
207 208
@@ -337,10 +338,25 @@ static int btmrvl_tx_pkt(struct btmrvl_private *priv, struct sk_buff *skb)
337 338
338static void btmrvl_init_adapter(struct btmrvl_private *priv) 339static void btmrvl_init_adapter(struct btmrvl_private *priv)
339{ 340{
341 int buf_size;
342
340 skb_queue_head_init(&priv->adapter->tx_queue); 343 skb_queue_head_init(&priv->adapter->tx_queue);
341 344
342 priv->adapter->ps_state = PS_AWAKE; 345 priv->adapter->ps_state = PS_AWAKE;
343 346
347 buf_size = ALIGN_SZ(SDIO_BLOCK_SIZE, BTSDIO_DMA_ALIGN);
348 priv->adapter->hw_regs_buf = kzalloc(buf_size, GFP_KERNEL);
349 if (!priv->adapter->hw_regs_buf) {
350 priv->adapter->hw_regs = NULL;
351 BT_ERR("Unable to allocate buffer for hw_regs.");
352 } else {
353 priv->adapter->hw_regs =
354 (u8 *)ALIGN_ADDR(priv->adapter->hw_regs_buf,
355 BTSDIO_DMA_ALIGN);
356 BT_DBG("hw_regs_buf=%p hw_regs=%p",
357 priv->adapter->hw_regs_buf, priv->adapter->hw_regs);
358 }
359
344 init_waitqueue_head(&priv->adapter->cmd_wait_q); 360 init_waitqueue_head(&priv->adapter->cmd_wait_q);
345} 361}
346 362
@@ -348,6 +364,7 @@ static void btmrvl_free_adapter(struct btmrvl_private *priv)
348{ 364{
349 skb_queue_purge(&priv->adapter->tx_queue); 365 skb_queue_purge(&priv->adapter->tx_queue);
350 366
367 kfree(priv->adapter->hw_regs_buf);
351 kfree(priv->adapter); 368 kfree(priv->adapter);
352 369
353 priv->adapter = NULL; 370 priv->adapter = NULL;
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 1b52c9f5230d..9dedca516ff5 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -64,6 +64,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = {
64 .io_port_0 = 0x00, 64 .io_port_0 = 0x00,
65 .io_port_1 = 0x01, 65 .io_port_1 = 0x01,
66 .io_port_2 = 0x02, 66 .io_port_2 = 0x02,
67 .int_read_to_clear = false,
67}; 68};
68static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { 69static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
69 .cfg = 0x00, 70 .cfg = 0x00,
@@ -80,6 +81,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
80 .io_port_0 = 0x78, 81 .io_port_0 = 0x78,
81 .io_port_1 = 0x79, 82 .io_port_1 = 0x79,
82 .io_port_2 = 0x7a, 83 .io_port_2 = 0x7a,
84 .int_read_to_clear = false,
83}; 85};
84 86
85static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = { 87static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
@@ -97,6 +99,9 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
97 .io_port_0 = 0xd8, 99 .io_port_0 = 0xd8,
98 .io_port_1 = 0xd9, 100 .io_port_1 = 0xd9,
99 .io_port_2 = 0xda, 101 .io_port_2 = 0xda,
102 .int_read_to_clear = true,
103 .host_int_rsr = 0x01,
104 .card_misc_cfg = 0xcc,
100}; 105};
101 106
102static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { 107static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
@@ -667,46 +672,78 @@ static int btmrvl_sdio_process_int_status(struct btmrvl_private *priv)
667 return 0; 672 return 0;
668} 673}
669 674
670static void btmrvl_sdio_interrupt(struct sdio_func *func) 675static int btmrvl_sdio_read_to_clear(struct btmrvl_sdio_card *card, u8 *ireg)
671{ 676{
672 struct btmrvl_private *priv; 677 struct btmrvl_adapter *adapter = card->priv->adapter;
673 struct btmrvl_sdio_card *card;
674 ulong flags;
675 u8 ireg = 0;
676 int ret; 678 int ret;
677 679
678 card = sdio_get_drvdata(func); 680 ret = sdio_readsb(card->func, adapter->hw_regs, 0, SDIO_BLOCK_SIZE);
679 if (!card || !card->priv) { 681 if (ret) {
680 BT_ERR("sbi_interrupt(%p) card or priv is " 682 BT_ERR("sdio_readsb: read int hw_regs failed: %d", ret);
681 "NULL, card=%p\n", func, card); 683 return ret;
682 return;
683 } 684 }
684 685
685 priv = card->priv; 686 *ireg = adapter->hw_regs[card->reg->host_intstatus];
687 BT_DBG("hw_regs[%#x]=%#x", card->reg->host_intstatus, *ireg);
688
689 return 0;
690}
686 691
687 ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret); 692static int btmrvl_sdio_write_to_clear(struct btmrvl_sdio_card *card, u8 *ireg)
693{
694 int ret;
695
696 *ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret);
688 if (ret) { 697 if (ret) {
689 BT_ERR("sdio_readb: read int status register failed"); 698 BT_ERR("sdio_readb: read int status failed: %d", ret);
690 return; 699 return ret;
691 } 700 }
692 701
693 if (ireg != 0) { 702 if (*ireg) {
694 /* 703 /*
695 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS 704 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
696 * Clear the interrupt status register and re-enable the 705 * Clear the interrupt status register and re-enable the
697 * interrupt. 706 * interrupt.
698 */ 707 */
699 BT_DBG("ireg = 0x%x", ireg); 708 BT_DBG("int_status = 0x%x", *ireg);
700 709
701 sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | 710 sdio_writeb(card->func, ~(*ireg) & (DN_LD_HOST_INT_STATUS |
702 UP_LD_HOST_INT_STATUS), 711 UP_LD_HOST_INT_STATUS),
703 card->reg->host_intstatus, &ret); 712 card->reg->host_intstatus, &ret);
704 if (ret) { 713 if (ret) {
705 BT_ERR("sdio_writeb: clear int status register failed"); 714 BT_ERR("sdio_writeb: clear int status failed: %d", ret);
706 return; 715 return ret;
707 } 716 }
708 } 717 }
709 718
719 return 0;
720}
721
722static void btmrvl_sdio_interrupt(struct sdio_func *func)
723{
724 struct btmrvl_private *priv;
725 struct btmrvl_sdio_card *card;
726 ulong flags;
727 u8 ireg = 0;
728 int ret;
729
730 card = sdio_get_drvdata(func);
731 if (!card || !card->priv) {
732 BT_ERR("sbi_interrupt(%p) card or priv is "
733 "NULL, card=%p\n", func, card);
734 return;
735 }
736
737 priv = card->priv;
738
739 if (card->reg->int_read_to_clear)
740 ret = btmrvl_sdio_read_to_clear(card, &ireg);
741 else
742 ret = btmrvl_sdio_write_to_clear(card, &ireg);
743
744 if (ret)
745 return;
746
710 spin_lock_irqsave(&priv->driver_lock, flags); 747 spin_lock_irqsave(&priv->driver_lock, flags);
711 sdio_ireg |= ireg; 748 sdio_ireg |= ireg;
712 spin_unlock_irqrestore(&priv->driver_lock, flags); 749 spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -777,6 +814,30 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
777 814
778 BT_DBG("SDIO FUNC%d IO port: 0x%x", func->num, card->ioport); 815 BT_DBG("SDIO FUNC%d IO port: 0x%x", func->num, card->ioport);
779 816
817 if (card->reg->int_read_to_clear) {
818 reg = sdio_readb(func, card->reg->host_int_rsr, &ret);
819 if (ret < 0) {
820 ret = -EIO;
821 goto release_irq;
822 }
823 sdio_writeb(func, reg | 0x3f, card->reg->host_int_rsr, &ret);
824 if (ret < 0) {
825 ret = -EIO;
826 goto release_irq;
827 }
828
829 reg = sdio_readb(func, card->reg->card_misc_cfg, &ret);
830 if (ret < 0) {
831 ret = -EIO;
832 goto release_irq;
833 }
834 sdio_writeb(func, reg | 0x10, card->reg->card_misc_cfg, &ret);
835 if (ret < 0) {
836 ret = -EIO;
837 goto release_irq;
838 }
839 }
840
780 sdio_set_drvdata(func, card); 841 sdio_set_drvdata(func, card);
781 842
782 sdio_release_host(func); 843 sdio_release_host(func);
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h
index 43d35a609ca9..d4dd3b0fa53d 100644
--- a/drivers/bluetooth/btmrvl_sdio.h
+++ b/drivers/bluetooth/btmrvl_sdio.h
@@ -78,6 +78,9 @@ struct btmrvl_sdio_card_reg {
78 u8 io_port_0; 78 u8 io_port_0;
79 u8 io_port_1; 79 u8 io_port_1;
80 u8 io_port_2; 80 u8 io_port_2;
81 bool int_read_to_clear;
82 u8 host_int_rsr;
83 u8 card_misc_cfg;
81}; 84};
82 85
83struct btmrvl_sdio_card { 86struct btmrvl_sdio_card {
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 7048a583fe51..66db9a803373 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -55,13 +55,6 @@ struct h4_struct {
55 struct sk_buff_head txq; 55 struct sk_buff_head txq;
56}; 56};
57 57
58/* H4 receiver States */
59#define H4_W4_PACKET_TYPE 0
60#define H4_W4_EVENT_HDR 1
61#define H4_W4_ACL_HDR 2
62#define H4_W4_SCO_HDR 3
63#define H4_W4_DATA 4
64
65/* Initialize protocol */ 58/* Initialize protocol */
66static int h4_open(struct hci_uart *hu) 59static int h4_open(struct hci_uart *hu)
67{ 60{