summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorSean Wang <sean.wang@mediatek.com>2019-04-18 05:08:02 -0400
committerMarcel Holtmann <marcel@holtmann.org>2019-04-23 12:36:20 -0400
commit7f3c563c575e73c689fe2762c5ec61159caa1568 (patch)
tree2aaeb8a67993ee2f5adf0464afe852ef2ae30961 /drivers/bluetooth
parentbcaa7d72dffddfa4196a37108d67fc12fb4edfca (diff)
Bluetooth: btmtksdio: Add runtime PM support to SDIO based Bluetooth
Add runtime PM support to btmtksdio. With this way, there will be the benefit of the device entering the more power saving state once it is been a while data traffic is idle. Signed-off-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/btmtksdio.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index 877c0a831775..813338288453 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -17,6 +17,7 @@
17#include <linux/iopoll.h> 17#include <linux/iopoll.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/pm_runtime.h>
20#include <linux/skbuff.h> 21#include <linux/skbuff.h>
21 22
22#include <linux/mmc/host.h> 23#include <linux/mmc/host.h>
@@ -33,6 +34,10 @@
33#define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin" 34#define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin"
34#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin" 35#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin"
35 36
37#define MTKBTSDIO_AUTOSUSPEND_DELAY 8000
38
39static bool enable_autosuspend;
40
36struct btmtksdio_data { 41struct btmtksdio_data {
37 const char *fwname; 42 const char *fwname;
38}; 43};
@@ -150,6 +155,7 @@ struct btmtk_hci_wmt_params {
150struct btmtksdio_dev { 155struct btmtksdio_dev {
151 struct hci_dev *hdev; 156 struct hci_dev *hdev;
152 struct sdio_func *func; 157 struct sdio_func *func;
158 struct device *dev;
153 159
154 struct work_struct tx_work; 160 struct work_struct tx_work;
155 unsigned long tx_state; 161 unsigned long tx_state;
@@ -301,6 +307,8 @@ static void btmtksdio_tx_work(struct work_struct *work)
301 struct sk_buff *skb; 307 struct sk_buff *skb;
302 int err; 308 int err;
303 309
310 pm_runtime_get_sync(bdev->dev);
311
304 sdio_claim_host(bdev->func); 312 sdio_claim_host(bdev->func);
305 313
306 while ((skb = skb_dequeue(&bdev->txq))) { 314 while ((skb = skb_dequeue(&bdev->txq))) {
@@ -313,6 +321,9 @@ static void btmtksdio_tx_work(struct work_struct *work)
313 } 321 }
314 322
315 sdio_release_host(bdev->func); 323 sdio_release_host(bdev->func);
324
325 pm_runtime_mark_last_busy(bdev->dev);
326 pm_runtime_put_autosuspend(bdev->dev);
316} 327}
317 328
318static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb) 329static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
@@ -471,6 +482,18 @@ static void btmtksdio_interrupt(struct sdio_func *func)
471 u32 int_status; 482 u32 int_status;
472 u16 rx_size; 483 u16 rx_size;
473 484
485 /* It is required that the host gets ownership from the device before
486 * accessing any register, however, if SDIO host is not being released,
487 * a potential deadlock probably happens in a circular wait between SDIO
488 * IRQ work and PM runtime work. So, we have to explicitly release SDIO
489 * host here and claim again after the PM runtime work is all done.
490 */
491 sdio_release_host(bdev->func);
492
493 pm_runtime_get_sync(bdev->dev);
494
495 sdio_claim_host(bdev->func);
496
474 /* Disable interrupt */ 497 /* Disable interrupt */
475 sdio_writel(func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0); 498 sdio_writel(func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0);
476 499
@@ -507,6 +530,9 @@ static void btmtksdio_interrupt(struct sdio_func *func)
507 530
508 /* Enable interrupt */ 531 /* Enable interrupt */
509 sdio_writel(func, C_INT_EN_SET, MTK_REG_CHLPCR, 0); 532 sdio_writel(func, C_INT_EN_SET, MTK_REG_CHLPCR, 0);
533
534 pm_runtime_mark_last_busy(bdev->dev);
535 pm_runtime_put_autosuspend(bdev->dev);
510} 536}
511 537
512static int btmtksdio_open(struct hci_dev *hdev) 538static int btmtksdio_open(struct hci_dev *hdev)
@@ -815,6 +841,23 @@ ignore_func_on:
815 delta = ktime_sub(rettime, calltime); 841 delta = ktime_sub(rettime, calltime);
816 duration = (unsigned long long)ktime_to_ns(delta) >> 10; 842 duration = (unsigned long long)ktime_to_ns(delta) >> 10;
817 843
844 pm_runtime_set_autosuspend_delay(bdev->dev,
845 MTKBTSDIO_AUTOSUSPEND_DELAY);
846 pm_runtime_use_autosuspend(bdev->dev);
847
848 err = pm_runtime_set_active(bdev->dev);
849 if (err < 0)
850 return err;
851
852 /* Default forbid runtime auto suspend, that can be allowed by
853 * enable_autosuspend flag or the PM runtime entry under sysfs.
854 */
855 pm_runtime_forbid(bdev->dev);
856 pm_runtime_enable(bdev->dev);
857
858 if (enable_autosuspend)
859 pm_runtime_allow(bdev->dev);
860
818 bt_dev_info(hdev, "Device setup in %llu usecs", duration); 861 bt_dev_info(hdev, "Device setup in %llu usecs", duration);
819 862
820 return 0; 863 return 0;
@@ -822,10 +865,16 @@ ignore_func_on:
822 865
823static int btmtksdio_shutdown(struct hci_dev *hdev) 866static int btmtksdio_shutdown(struct hci_dev *hdev)
824{ 867{
868 struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
825 struct btmtk_hci_wmt_params wmt_params; 869 struct btmtk_hci_wmt_params wmt_params;
826 u8 param = 0x0; 870 u8 param = 0x0;
827 int err; 871 int err;
828 872
873 /* Get back the state to be consistent with the state
874 * in btmtksdio_setup.
875 */
876 pm_runtime_get_sync(bdev->dev);
877
829 /* Disable the device */ 878 /* Disable the device */
830 wmt_params.op = MTK_WMT_FUNC_CTRL; 879 wmt_params.op = MTK_WMT_FUNC_CTRL;
831 wmt_params.flag = 0; 880 wmt_params.flag = 0;
@@ -839,6 +888,9 @@ static int btmtksdio_shutdown(struct hci_dev *hdev)
839 return err; 888 return err;
840 } 889 }
841 890
891 pm_runtime_put_noidle(bdev->dev);
892 pm_runtime_disable(bdev->dev);
893
842 return 0; 894 return 0;
843} 895}
844 896
@@ -885,6 +937,7 @@ static int btmtksdio_probe(struct sdio_func *func,
885 if (!bdev->data) 937 if (!bdev->data)
886 return -ENODEV; 938 return -ENODEV;
887 939
940 bdev->dev = &func->dev;
888 bdev->func = func; 941 bdev->func = func;
889 942
890 INIT_WORK(&bdev->tx_work, btmtksdio_tx_work); 943 INIT_WORK(&bdev->tx_work, btmtksdio_tx_work);
@@ -922,6 +975,25 @@ static int btmtksdio_probe(struct sdio_func *func,
922 975
923 sdio_set_drvdata(func, bdev); 976 sdio_set_drvdata(func, bdev);
924 977
978 /* pm_runtime_enable would be done after the firmware is being
979 * downloaded because the core layer probably already enables
980 * runtime PM for this func such as the case host->caps &
981 * MMC_CAP_POWER_OFF_CARD.
982 */
983 if (pm_runtime_enabled(bdev->dev))
984 pm_runtime_disable(bdev->dev);
985
986 /* As explaination in drivers/mmc/core/sdio_bus.c tells us:
987 * Unbound SDIO functions are always suspended.
988 * During probe, the function is set active and the usage count
989 * is incremented. If the driver supports runtime PM,
990 * it should call pm_runtime_put_noidle() in its probe routine and
991 * pm_runtime_get_noresume() in its remove routine.
992 *
993 * So, put a pm_runtime_put_noidle here !
994 */
995 pm_runtime_put_noidle(bdev->dev);
996
925 return 0; 997 return 0;
926} 998}
927 999
@@ -933,6 +1005,9 @@ static void btmtksdio_remove(struct sdio_func *func)
933 if (!bdev) 1005 if (!bdev)
934 return; 1006 return;
935 1007
1008 /* Be consistent the state in btmtksdio_probe */
1009 pm_runtime_get_noresume(bdev->dev);
1010
936 hdev = bdev->hdev; 1011 hdev = bdev->hdev;
937 1012
938 sdio_set_drvdata(func, NULL); 1013 sdio_set_drvdata(func, NULL);
@@ -940,15 +1015,84 @@ static void btmtksdio_remove(struct sdio_func *func)
940 hci_free_dev(hdev); 1015 hci_free_dev(hdev);
941} 1016}
942 1017
1018#ifdef CONFIG_PM
1019static int btmtksdio_runtime_suspend(struct device *dev)
1020{
1021 struct sdio_func *func = dev_to_sdio_func(dev);
1022 struct btmtksdio_dev *bdev;
1023 u32 status;
1024 int err;
1025
1026 bdev = sdio_get_drvdata(func);
1027 if (!bdev)
1028 return 0;
1029
1030 sdio_claim_host(bdev->func);
1031
1032 sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err);
1033 if (err < 0)
1034 goto out;
1035
1036 err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
1037 !(status & C_COM_DRV_OWN), 2000, 1000000);
1038out:
1039 bt_dev_info(bdev->hdev, "status (%d) return ownership to device", err);
1040
1041 sdio_release_host(bdev->func);
1042
1043 return err;
1044}
1045
1046static int btmtksdio_runtime_resume(struct device *dev)
1047{
1048 struct sdio_func *func = dev_to_sdio_func(dev);
1049 struct btmtksdio_dev *bdev;
1050 u32 status;
1051 int err;
1052
1053 bdev = sdio_get_drvdata(func);
1054 if (!bdev)
1055 return 0;
1056
1057 sdio_claim_host(bdev->func);
1058
1059 sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err);
1060 if (err < 0)
1061 goto out;
1062
1063 err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
1064 status & C_COM_DRV_OWN, 2000, 1000000);
1065out:
1066 bt_dev_info(bdev->hdev, "status (%d) get ownership from device", err);
1067
1068 sdio_release_host(bdev->func);
1069
1070 return err;
1071}
1072
1073static UNIVERSAL_DEV_PM_OPS(btmtksdio_pm_ops, btmtksdio_runtime_suspend,
1074 btmtksdio_runtime_resume, NULL);
1075#define BTMTKSDIO_PM_OPS (&btmtksdio_pm_ops)
1076#else /* CONFIG_PM */
1077#define BTMTKSDIO_PM_OPS NULL
1078#endif /* CONFIG_PM */
1079
943static struct sdio_driver btmtksdio_driver = { 1080static struct sdio_driver btmtksdio_driver = {
944 .name = "btmtksdio", 1081 .name = "btmtksdio",
945 .probe = btmtksdio_probe, 1082 .probe = btmtksdio_probe,
946 .remove = btmtksdio_remove, 1083 .remove = btmtksdio_remove,
947 .id_table = btmtksdio_table, 1084 .id_table = btmtksdio_table,
1085 .drv = {
1086 .owner = THIS_MODULE,
1087 .pm = BTMTKSDIO_PM_OPS,
1088 }
948}; 1089};
949 1090
950module_sdio_driver(btmtksdio_driver); 1091module_sdio_driver(btmtksdio_driver);
951 1092
1093module_param(enable_autosuspend, bool, 0644);
1094MODULE_PARM_DESC(enable_autosuspend, "Enable autosuspend by default");
1095
952MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); 1096MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
953MODULE_DESCRIPTION("MediaTek Bluetooth SDIO driver ver " VERSION); 1097MODULE_DESCRIPTION("MediaTek Bluetooth SDIO driver ver " VERSION);
954MODULE_VERSION(VERSION); 1098MODULE_VERSION(VERSION);