Re: [PATCH v3 2/2] Bluetooth: hci_h5: Add flag for keep power during suspend/resume

From: Marcel Holtmann
Date: Fri Apr 23 2021 - 02:55:02 EST


Hi Hilda,

> RTL8822C and RTL8852A devices support BT wakeup Host. Add a flag
> for these specific devices did not power off during suspend and resume.
> By this change, if the Host support that received BT device signal then
> it can wake Host up.
>
> Signed-off-by: hildawu <hildawu@xxxxxxxxxxx>
> ---
> Changed in v3:
> - Reworked to use UART flag, refer to Maintainer's suggestion.
> - Split into two patches for different purpose.
>
> Changes in v2:
> - Add the missing struct member
> - Modify title length
> ---
> ---
> drivers/bluetooth/hci_h5.c | 34 ++++++++++++++++++++++++----------
> drivers/bluetooth/hci_ldisc.c | 3 ++-
> drivers/bluetooth/hci_uart.h | 1 +
> 3 files changed, 27 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
> index 27e96681d583..9cacc4cdc928 100644
> --- a/drivers/bluetooth/hci_h5.c
> +++ b/drivers/bluetooth/hci_h5.c
> @@ -911,6 +911,15 @@ static int h5_btrtl_setup(struct h5 *h5)
> */
> set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &h5->hu->hdev->quirks);
>
> + switch (btrtl_dev->project_id) {
> + case CHIP_ID_8822C:
> + case CHIP_ID_8852A:
> + set_bit(HCI_UART_WAKEUP_ENABLE, &h5->hu->hdev_flags);
> + break;
> + default:
> + break;
> + }
> +
> out_free:
> btrtl_free(btrtl_dev);
>
> @@ -945,8 +954,11 @@ static void h5_btrtl_close(struct h5 *h5)
> 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(HCI_UART_WAKEUP_ENABLE, &h5->hu->hdev_flags)) {
> + gpiod_set_value_cansleep(h5->device_wake_gpio, 0);
> + gpiod_set_value_cansleep(h5->enable_gpio, 0);
> + }
> return 0;
> }
>
> @@ -972,17 +984,19 @@ 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(HCI_UART_WAKEUP_ENABLE, &h5->hu->hdev_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);
> + }
> return 0;
> }
>
> diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
> index 637c5b8c2aa1..3a1038e9dc6a 100644
> --- a/drivers/bluetooth/hci_ldisc.c
> +++ b/drivers/bluetooth/hci_ldisc.c
> @@ -719,7 +719,8 @@ static int hci_uart_set_flags(struct hci_uart *hu, unsigned long flags)
> BIT(HCI_UART_CREATE_AMP) |
> BIT(HCI_UART_INIT_PENDING) |
> BIT(HCI_UART_EXT_CONFIG) |
> - BIT(HCI_UART_VND_DETECT);
> + BIT(HCI_UART_VND_DETECT) |
> + BIT(HCI_UART_WAKEUP_ENABLE);
>
> if (flags & ~valid_flags)
> return -EINVAL;
> diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
> index 4e039d7a16f8..25f5e5c7544c 100644
> --- a/drivers/bluetooth/hci_uart.h
> +++ b/drivers/bluetooth/hci_uart.h
> @@ -41,6 +41,7 @@
> #define HCI_UART_INIT_PENDING 3
> #define HCI_UART_EXT_CONFIG 4
> #define HCI_UART_VND_DETECT 5
> +#define HCI_UART_WAKEUP_ENABLE 6

don’t use these flags since they are an ioctl API.

Regards

Marcel