diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-04-30 11:56:43 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-04-30 11:56:43 -0400 |
commit | 0006433a5be9e0e155ad493e33c6e9bf3868a87f (patch) | |
tree | 3993166ba48d5c6259c04c836c5b4bd5f4643b85 /drivers/bluetooth | |
parent | bb0f8609ba9a41aa7a24109926a0f540dc2a7c6d (diff) | |
parent | 22e70786413ed05950207eda7be420c280b776d7 (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.h | 4 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_main.c | 19 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.c | 103 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.h | 3 | ||||
-rw-r--r-- | drivers/bluetooth/hci_h4.c | 7 |
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 | ||
61 | struct btmrvl_adapter { | 61 | struct 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); | |||
140 | bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); | 142 | bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); |
141 | int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); | 143 | int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); |
142 | 144 | ||
143 | int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); | 145 | int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd); |
144 | int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv); | 146 | int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv); |
145 | int btmrvl_enable_ps(struct btmrvl_private *priv); | 147 | int btmrvl_enable_ps(struct btmrvl_private *priv); |
146 | int btmrvl_prepare_command(struct btmrvl_private *priv); | 148 | int 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 | ||
204 | int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd) | 205 | int 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 | ||
338 | static void btmrvl_init_adapter(struct btmrvl_private *priv) | 339 | static 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 | }; |
68 | static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { | 69 | static 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 | ||
85 | static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = { | 87 | static 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 | ||
102 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { | 107 | static 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 | ||
670 | static void btmrvl_sdio_interrupt(struct sdio_func *func) | 675 | static 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); | 692 | static 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 | |||
722 | static 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 | ||
83 | struct btmrvl_sdio_card { | 86 | struct 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 */ |
66 | static int h4_open(struct hci_uart *hu) | 59 | static int h4_open(struct hci_uart *hu) |
67 | { | 60 | { |