LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 1/3] Bluetooth: hci_h5: add WAKEUP_DISABLE flag
@ 2021-07-14 7:13 Archie Pusaka
2021-07-14 7:13 ` [PATCH 2/3] Bluetooth: hci_h5: btrtl: Maintain flow control if wakeup is enabled Archie Pusaka
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Archie Pusaka @ 2021-07-14 7:13 UTC (permalink / raw)
To: linux-bluetooth, Marcel Holtmann
Cc: CrosBT Upstreaming, Archie Pusaka, Abhishek Pandit-Subedi,
Hilda Wu, Johan Hedberg, Luiz Augusto von Dentz, linux-kernel
From: Archie Pusaka <apusaka@chromium.org>
Some RTL chips resets the FW on suspend, so wakeup is disabled on
those chips. This patch introduces this WAKEUP_DISABLE flag so that
chips that doesn't reset FW on suspend can leave the flag unset and
is allowed to wake the host.
This patch also left RTL8822 WAKEUP_DISABLE flag unset, therefore
allowing it to wake the host, and preventing reprobing on resume.
Signed-off-by: Archie Pusaka <apusaka@chromium.org>
Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-by: Hilda Wu <hildawu@realtek.com>
---
drivers/bluetooth/hci_h5.c | 86 +++++++++++++++++++++++++++-----------
1 file changed, 62 insertions(+), 24 deletions(-)
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 7b985c7cd26d..947246569434 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -51,8 +51,9 @@
/* H5 state flags */
enum {
- H5_RX_ESC, /* SLIP escape mode */
- H5_TX_ACK_REQ, /* Pending ack to send */
+ H5_RX_ESC, /* SLIP escape mode */
+ H5_TX_ACK_REQ, /* Pending ack to send */
+ H5_WAKEUP_DISABLE, /* Device cannot wake host */
};
struct h5 {
@@ -97,6 +98,10 @@ struct h5 {
struct gpio_desc *device_wake_gpio;
};
+enum h5_driver_info {
+ H5_INFO_WAKEUP_DISABLE = BIT(0),
+};
+
struct h5_vnd {
int (*setup)(struct h5 *h5);
void (*open)(struct h5 *h5);
@@ -106,6 +111,11 @@ struct h5_vnd {
const struct acpi_gpio_mapping *acpi_gpio_map;
};
+struct h5_device_data {
+ uint32_t driver_info;
+ struct h5_vnd *vnd;
+};
+
static void h5_reset_rx(struct h5 *h5);
static void h5_link_control(struct hci_uart *hu, const void *data, size_t len)
@@ -791,6 +801,9 @@ static int h5_serdev_probe(struct serdev_device *serdev)
{
struct device *dev = &serdev->dev;
struct h5 *h5;
+ struct hci_dev *hdev;
+ const struct h5_device_data *data;
+ int err;
h5 = devm_kzalloc(dev, sizeof(*h5), GFP_KERNEL);
if (!h5)
@@ -807,20 +820,19 @@ static int h5_serdev_probe(struct serdev_device *serdev)
if (!match)
return -ENODEV;
- h5->vnd = (const struct h5_vnd *)match->driver_data;
+ data = (const struct h5_device_data *)match->driver_data;
+ h5->vnd = data->vnd;
h5->id = (char *)match->id;
if (h5->vnd->acpi_gpio_map)
devm_acpi_dev_add_driver_gpios(dev,
h5->vnd->acpi_gpio_map);
} else {
- const void *data;
-
data = of_device_get_match_data(dev);
if (!data)
return -ENODEV;
- h5->vnd = (const struct h5_vnd *)data;
+ h5->vnd = data->vnd;
}
@@ -833,7 +845,16 @@ static int h5_serdev_probe(struct serdev_device *serdev)
if (IS_ERR(h5->device_wake_gpio))
return PTR_ERR(h5->device_wake_gpio);
- return hci_uart_register_device(&h5->serdev_hu, &h5p);
+ err = hci_uart_register_device(&h5->serdev_hu, &h5p);
+ if (err)
+ return err;
+
+ hdev = h5->serdev_hu.hdev;
+
+ if (data->driver_info & H5_INFO_WAKEUP_DISABLE)
+ set_bit(H5_WAKEUP_DISABLE, &h5->flags);
+
+ return 0;
}
static void h5_serdev_remove(struct serdev_device *serdev)
@@ -921,7 +942,8 @@ static void h5_btrtl_open(struct h5 *h5)
* done by the hci_suspend_notifier is not necessary; it actually causes
* delays and a bunch of errors to get logged, so disable it.
*/
- set_bit(HCI_UART_NO_SUSPEND_NOTIFIER, &h5->hu->flags);
+ if (test_bit(H5_WAKEUP_DISABLE, &h5->flags))
+ set_bit(HCI_UART_NO_SUSPEND_NOTIFIER, &h5->hu->flags);
/* Devices always start with these fixed parameters */
serdev_device_set_flow_control(h5->hu->serdev, false);
@@ -942,15 +964,18 @@ static void h5_btrtl_close(struct h5 *h5)
/* Suspend/resume support. On many devices the RTL BT device loses power during
* suspend/resume, causing it to lose its firmware and all state. So we simply
- * turn it off on suspend and reprobe on resume. This mirrors how RTL devices
- * are handled in the USB driver, where the USB_QUIRK_RESET_RESUME is used which
+ * turn it off on suspend and reprobe on resume. This mirrors how RTL devices
+ * are handled in the USB driver, where the BTUSB_WAKEUP_DISABLE is used which
* also causes a reprobe on resume.
*/
static int h5_btrtl_suspend(struct h5 *h5)
{
serdev_device_set_flow_control(h5->hu->serdev, false);
gpiod_set_value_cansleep(h5->device_wake_gpio, 0);
- gpiod_set_value_cansleep(h5->enable_gpio, 0);
+
+ if (test_bit(H5_WAKEUP_DISABLE, &h5->flags))
+ gpiod_set_value_cansleep(h5->enable_gpio, 0);
+
return 0;
}
@@ -976,17 +1001,21 @@ static void h5_btrtl_reprobe_worker(struct work_struct *work)
static int h5_btrtl_resume(struct h5 *h5)
{
- struct h5_btrtl_reprobe *reprobe;
+ if (test_bit(H5_WAKEUP_DISABLE, &h5->flags)) {
+ struct h5_btrtl_reprobe *reprobe;
- reprobe = kzalloc(sizeof(*reprobe), GFP_KERNEL);
- if (!reprobe)
- return -ENOMEM;
+ reprobe = kzalloc(sizeof(*reprobe), GFP_KERNEL);
+ if (!reprobe)
+ return -ENOMEM;
- __module_get(THIS_MODULE);
+ __module_get(THIS_MODULE);
- INIT_WORK(&reprobe->work, h5_btrtl_reprobe_worker);
- reprobe->dev = get_device(&h5->hu->serdev->dev);
- queue_work(system_long_wq, &reprobe->work);
+ INIT_WORK(&reprobe->work, h5_btrtl_reprobe_worker);
+ reprobe->dev = get_device(&h5->hu->serdev->dev);
+ queue_work(system_long_wq, &reprobe->work);
+ } else {
+ gpiod_set_value_cansleep(h5->device_wake_gpio, 1);
+ }
return 0;
}
@@ -1008,13 +1037,22 @@ static struct h5_vnd rtl_vnd = {
.resume = h5_btrtl_resume,
.acpi_gpio_map = acpi_btrtl_gpios,
};
+
+static const struct h5_device_data h5_data_rtl8822cs = {
+ .vnd = &rtl_vnd,
+};
+
+static const struct h5_device_data h5_data_rtl8723bs = {
+ .driver_info = H5_INFO_WAKEUP_DISABLE,
+ .vnd = &rtl_vnd,
+};
#endif
#ifdef CONFIG_ACPI
static const struct acpi_device_id h5_acpi_match[] = {
#ifdef CONFIG_BT_HCIUART_RTL
- { "OBDA0623", (kernel_ulong_t)&rtl_vnd },
- { "OBDA8723", (kernel_ulong_t)&rtl_vnd },
+ { "OBDA0623", (kernel_ulong_t)&h5_data_rtl8723bs },
+ { "OBDA8723", (kernel_ulong_t)&h5_data_rtl8723bs },
#endif
{ },
};
@@ -1028,11 +1066,11 @@ static const struct dev_pm_ops h5_serdev_pm_ops = {
static const struct of_device_id rtl_bluetooth_of_match[] = {
#ifdef CONFIG_BT_HCIUART_RTL
{ .compatible = "realtek,rtl8822cs-bt",
- .data = (const void *)&rtl_vnd },
+ .data = (const void *)&h5_data_rtl8822cs },
{ .compatible = "realtek,rtl8723bs-bt",
- .data = (const void *)&rtl_vnd },
+ .data = (const void *)&h5_data_rtl8723bs },
{ .compatible = "realtek,rtl8723ds-bt",
- .data = (const void *)&rtl_vnd },
+ .data = (const void *)&h5_data_rtl8723bs },
#endif
{ },
};
--
2.32.0.93.g670b81a890-goog
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/3] Bluetooth: hci_h5: btrtl: Maintain flow control if wakeup is enabled
2021-07-14 7:13 [PATCH 1/3] Bluetooth: hci_h5: add WAKEUP_DISABLE flag Archie Pusaka
@ 2021-07-14 7:13 ` Archie Pusaka
2021-07-14 7:13 ` [PATCH 3/3] Bluetooth: hci_h5: Add runtime suspend Archie Pusaka
2021-07-14 11:00 ` [PATCH 1/3] Bluetooth: hci_h5: add WAKEUP_DISABLE flag kernel test robot
2 siblings, 0 replies; 4+ messages in thread
From: Archie Pusaka @ 2021-07-14 7:13 UTC (permalink / raw)
To: linux-bluetooth, Marcel Holtmann
Cc: CrosBT Upstreaming, Archie Pusaka, Abhishek Pandit-Subedi,
Hilda Wu, Johan Hedberg, Luiz Augusto von Dentz, linux-kernel
From: Archie Pusaka <apusaka@chromium.org>
For chips that doesn't reset on suspend, we need to provide the correct
value of flow_control when it resumes. Therefore, store the flow
control value when reading from the config file to be reused upon
suspend.
Signed-off-by: Archie Pusaka <apusaka@chromium.org>
Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-by: Hilda Wu <hildawu@realtek.com>
---
drivers/bluetooth/hci_h5.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 947246569434..67fcf192d5c5 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -54,6 +54,7 @@ enum {
H5_RX_ESC, /* SLIP escape mode */
H5_TX_ACK_REQ, /* Pending ack to send */
H5_WAKEUP_DISABLE, /* Device cannot wake host */
+ H5_HW_FLOW_CONTROL, /* Use HW flow control */
};
struct h5 {
@@ -923,6 +924,9 @@ static int h5_btrtl_setup(struct h5 *h5)
serdev_device_set_baudrate(h5->hu->serdev, controller_baudrate);
serdev_device_set_flow_control(h5->hu->serdev, flow_control);
+ if (flow_control)
+ set_bit(H5_HW_FLOW_CONTROL, &h5->flags);
+
err = btrtl_download_firmware(h5->hu->hdev, btrtl_dev);
/* Give the device some time before the hci-core sends it a reset */
usleep_range(10000, 20000);
@@ -1015,7 +1019,11 @@ static int h5_btrtl_resume(struct h5 *h5)
queue_work(system_long_wq, &reprobe->work);
} else {
gpiod_set_value_cansleep(h5->device_wake_gpio, 1);
+
+ if (test_bit(H5_HW_FLOW_CONTROL, &h5->flags))
+ serdev_device_set_flow_control(h5->hu->serdev, true);
}
+
return 0;
}
--
2.32.0.93.g670b81a890-goog
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 3/3] Bluetooth: hci_h5: Add runtime suspend
2021-07-14 7:13 [PATCH 1/3] Bluetooth: hci_h5: add WAKEUP_DISABLE flag Archie Pusaka
2021-07-14 7:13 ` [PATCH 2/3] Bluetooth: hci_h5: btrtl: Maintain flow control if wakeup is enabled Archie Pusaka
@ 2021-07-14 7:13 ` Archie Pusaka
2021-07-14 11:00 ` [PATCH 1/3] Bluetooth: hci_h5: add WAKEUP_DISABLE flag kernel test robot
2 siblings, 0 replies; 4+ messages in thread
From: Archie Pusaka @ 2021-07-14 7:13 UTC (permalink / raw)
To: linux-bluetooth, Marcel Holtmann
Cc: CrosBT Upstreaming, Archie Pusaka, Abhishek Pandit-Subedi,
Hilda Wu, Johan Hedberg, Luiz Augusto von Dentz, linux-kernel
From: Archie Pusaka <apusaka@chromium.org>
This patch allows the controller to suspend after a short period of
inactivity.
Signed-off-by: Archie Pusaka <apusaka@chromium.org>
Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-by: Hilda Wu <hildawu@realtek.com>
---
drivers/bluetooth/hci_h5.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 67fcf192d5c5..41039cadd6f8 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -11,6 +11,7 @@
#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
+#include <linux/pm_runtime.h>
#include <linux/of_device.h>
#include <linux/serdev.h>
#include <linux/skbuff.h>
@@ -21,6 +22,8 @@
#include "btrtl.h"
#include "hci_uart.h"
+#define SUSPEND_TIMEOUT_MS 6000
+
#define HCI_3WIRE_ACK_PKT 0
#define HCI_3WIRE_LINK_PKT 15
@@ -584,6 +587,10 @@ static int h5_recv(struct hci_uart *hu, const void *data, int count)
count -= processed;
}
+ pm_runtime_get(&hu->serdev->dev);
+ pm_runtime_mark_last_busy(&hu->serdev->dev);
+ pm_runtime_put_autosuspend(&hu->serdev->dev);
+
return 0;
}
@@ -620,6 +627,10 @@ static int h5_enqueue(struct hci_uart *hu, struct sk_buff *skb)
break;
}
+ pm_runtime_get_sync(&hu->serdev->dev);
+ pm_runtime_mark_last_busy(&hu->serdev->dev);
+ pm_runtime_put_autosuspend(&hu->serdev->dev);
+
return 0;
}
@@ -954,6 +965,12 @@ static void h5_btrtl_open(struct h5 *h5)
serdev_device_set_parity(h5->hu->serdev, SERDEV_PARITY_EVEN);
serdev_device_set_baudrate(h5->hu->serdev, 115200);
+ pm_runtime_set_active(&h5->hu->serdev->dev);
+ pm_runtime_use_autosuspend(&h5->hu->serdev->dev);
+ pm_runtime_set_autosuspend_delay(&h5->hu->serdev->dev,
+ SUSPEND_TIMEOUT_MS);
+ pm_runtime_enable(&h5->hu->serdev->dev);
+
/* The controller needs up to 500ms to wakeup */
gpiod_set_value_cansleep(h5->enable_gpio, 1);
gpiod_set_value_cansleep(h5->device_wake_gpio, 1);
@@ -962,6 +979,8 @@ static void h5_btrtl_open(struct h5 *h5)
static void h5_btrtl_close(struct h5 *h5)
{
+ pm_runtime_disable(&h5->hu->serdev->dev);
+
gpiod_set_value_cansleep(h5->device_wake_gpio, 0);
gpiod_set_value_cansleep(h5->enable_gpio, 0);
}
@@ -1069,6 +1088,7 @@ MODULE_DEVICE_TABLE(acpi, h5_acpi_match);
static const struct dev_pm_ops h5_serdev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(h5_serdev_suspend, h5_serdev_resume)
+ SET_RUNTIME_PM_OPS(h5_serdev_suspend, h5_serdev_resume, NULL)
};
static const struct of_device_id rtl_bluetooth_of_match[] = {
--
2.32.0.93.g670b81a890-goog
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/3] Bluetooth: hci_h5: add WAKEUP_DISABLE flag
2021-07-14 7:13 [PATCH 1/3] Bluetooth: hci_h5: add WAKEUP_DISABLE flag Archie Pusaka
2021-07-14 7:13 ` [PATCH 2/3] Bluetooth: hci_h5: btrtl: Maintain flow control if wakeup is enabled Archie Pusaka
2021-07-14 7:13 ` [PATCH 3/3] Bluetooth: hci_h5: Add runtime suspend Archie Pusaka
@ 2021-07-14 11:00 ` kernel test robot
2 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-07-14 11:00 UTC (permalink / raw)
To: Archie Pusaka, linux-bluetooth, Marcel Holtmann
Cc: kbuild-all, CrosBT Upstreaming, Archie Pusaka,
Abhishek Pandit-Subedi, Hilda Wu, Johan Hedberg,
Luiz Augusto von Dentz, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 3709 bytes --]
Hi Archie,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on bluetooth-next/master]
[also build test WARNING on next-20210714]
[cannot apply to bluetooth/master v5.14-rc1]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Archie-Pusaka/Bluetooth-hci_h5-add-WAKEUP_DISABLE-flag/20210714-151525
base: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/865118c4aaa9efbd4776dee71bf3a1a263a6571e
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Archie-Pusaka/Bluetooth-hci_h5-add-WAKEUP_DISABLE-flag/20210714-151525
git checkout 865118c4aaa9efbd4776dee71bf3a1a263a6571e
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=xtensa
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/bluetooth/hci_h5.c: In function 'h5_serdev_probe':
>> drivers/bluetooth/hci_h5.c:804:18: warning: variable 'hdev' set but not used [-Wunused-but-set-variable]
804 | struct hci_dev *hdev;
| ^~~~
vim +/hdev +804 drivers/bluetooth/hci_h5.c
799
800 static int h5_serdev_probe(struct serdev_device *serdev)
801 {
802 struct device *dev = &serdev->dev;
803 struct h5 *h5;
> 804 struct hci_dev *hdev;
805 const struct h5_device_data *data;
806 int err;
807
808 h5 = devm_kzalloc(dev, sizeof(*h5), GFP_KERNEL);
809 if (!h5)
810 return -ENOMEM;
811
812 h5->hu = &h5->serdev_hu;
813 h5->serdev_hu.serdev = serdev;
814 serdev_device_set_drvdata(serdev, h5);
815
816 if (has_acpi_companion(dev)) {
817 const struct acpi_device_id *match;
818
819 match = acpi_match_device(dev->driver->acpi_match_table, dev);
820 if (!match)
821 return -ENODEV;
822
823 data = (const struct h5_device_data *)match->driver_data;
824 h5->vnd = data->vnd;
825 h5->id = (char *)match->id;
826
827 if (h5->vnd->acpi_gpio_map)
828 devm_acpi_dev_add_driver_gpios(dev,
829 h5->vnd->acpi_gpio_map);
830 } else {
831 data = of_device_get_match_data(dev);
832 if (!data)
833 return -ENODEV;
834
835 h5->vnd = data->vnd;
836 }
837
838
839 h5->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
840 if (IS_ERR(h5->enable_gpio))
841 return PTR_ERR(h5->enable_gpio);
842
843 h5->device_wake_gpio = devm_gpiod_get_optional(dev, "device-wake",
844 GPIOD_OUT_LOW);
845 if (IS_ERR(h5->device_wake_gpio))
846 return PTR_ERR(h5->device_wake_gpio);
847
848 err = hci_uart_register_device(&h5->serdev_hu, &h5p);
849 if (err)
850 return err;
851
852 hdev = h5->serdev_hu.hdev;
853
854 if (data->driver_info & H5_INFO_WAKEUP_DISABLE)
855 set_bit(H5_WAKEUP_DISABLE, &h5->flags);
856
857 return 0;
858 }
859
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 68070 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-07-14 11:01 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-14 7:13 [PATCH 1/3] Bluetooth: hci_h5: add WAKEUP_DISABLE flag Archie Pusaka
2021-07-14 7:13 ` [PATCH 2/3] Bluetooth: hci_h5: btrtl: Maintain flow control if wakeup is enabled Archie Pusaka
2021-07-14 7:13 ` [PATCH 3/3] Bluetooth: hci_h5: Add runtime suspend Archie Pusaka
2021-07-14 11:00 ` [PATCH 1/3] Bluetooth: hci_h5: add WAKEUP_DISABLE flag kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).