Message ID | 20190917212702.35747-3-abhishekpandit@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Reset realtek bluetooth devices during user suspend | expand |
On Tue, Sep 17, 2019 at 02:27:02PM -0700, Abhishek Pandit-Subedi wrote: > Reset realtek devices on user suspend if not configured as a wakeup source. > > Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> > --- > > drivers/bluetooth/btusb.c | 26 ++++++++++++++++++++++++++ > 1 file changed, 26 insertions(+) > > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c > index a9c35ebb30f8..ce3a10642f4e 100644 > --- a/drivers/bluetooth/btusb.c > +++ b/drivers/bluetooth/btusb.c > @@ -493,6 +493,8 @@ struct btusb_data { > > int oob_wake_irq; /* irq for out-of-band wake-on-bt */ > unsigned cmd_timeout_cnt; > + > + bool reset_on_suspend; /* reset on suspend if not a wakeup source */ > }; > > > @@ -3818,6 +3820,8 @@ static int btusb_probe(struct usb_interface *intf, > * (DEVICE_REMOTE_WAKEUP) > */ > set_bit(BTUSB_WAKEUP_DISABLE, &data->flags); > + /* We'll explicitly reset the device around user suspend too. */ > + data->reset_on_suspend = true; > } > #endif > > @@ -4007,6 +4011,22 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) > return 0; > } > > +static int btusb_suspend_noirq(struct usb_interface *intf, pm_message_t message) > +{ > + struct btusb_data *data = usb_get_intfdata(intf); > + > + BT_DBG("suspend_noirq %p", intf); > + > + /* Only reset if not configured for wakeup */ > + if (!device_may_wakeup(&data->udev->dev) && > + data->reset_on_suspend && data->reset_gpio) { > + BT_DBG("resetting in suspend_noirq\n"); > + gpiod_set_value_cansleep(data->reset_gpio, 1); That's a totally out-of-band message for a USB driver to do. Why can it suddenly set a GPIO pin and not talk to the USB device here? If this is a GPIO driver, then why not get the suspend message from that subsystem? greg k-h
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index a9c35ebb30f8..ce3a10642f4e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -493,6 +493,8 @@ struct btusb_data { int oob_wake_irq; /* irq for out-of-band wake-on-bt */ unsigned cmd_timeout_cnt; + + bool reset_on_suspend; /* reset on suspend if not a wakeup source */ }; @@ -3818,6 +3820,8 @@ static int btusb_probe(struct usb_interface *intf, * (DEVICE_REMOTE_WAKEUP) */ set_bit(BTUSB_WAKEUP_DISABLE, &data->flags); + /* We'll explicitly reset the device around user suspend too. */ + data->reset_on_suspend = true; } #endif @@ -4007,6 +4011,22 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) return 0; } +static int btusb_suspend_noirq(struct usb_interface *intf, pm_message_t message) +{ + struct btusb_data *data = usb_get_intfdata(intf); + + BT_DBG("suspend_noirq %p", intf); + + /* Only reset if not configured for wakeup */ + if (!device_may_wakeup(&data->udev->dev) && + data->reset_on_suspend && data->reset_gpio) { + BT_DBG("resetting in suspend_noirq\n"); + gpiod_set_value_cansleep(data->reset_gpio, 1); + } + + return 0; +} + static void play_deferred(struct btusb_data *data) { struct urb *urb; @@ -4048,6 +4068,11 @@ static int btusb_resume(struct usb_interface *intf) if (--data->suspend_count) return 0; + if (data->reset_on_suspend && data->reset_gpio) { + BT_DBG("restoring reset in resume\n"); + gpiod_set_value_cansleep(data->reset_gpio, 0); + } + /* Disable only if not already disabled (keep it balanced) */ if (test_and_clear_bit(BTUSB_OOB_WAKE_ENABLED, &data->flags)) { disable_irq(data->oob_wake_irq); @@ -4107,6 +4132,7 @@ static struct usb_driver btusb_driver = { .disconnect = btusb_disconnect, #ifdef CONFIG_PM .suspend = btusb_suspend, + .suspend_noirq = btusb_suspend_noirq, .resume = btusb_resume, #endif .id_table = btusb_table,
Reset realtek devices on user suspend if not configured as a wakeup source. Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> --- drivers/bluetooth/btusb.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)