mbox series

[0/2] Reset realtek bluetooth devices during user suspend

Message ID 20190917212702.35747-1-abhishekpandit@chromium.org (mailing list archive)
Headers show
Series Reset realtek bluetooth devices during user suspend | expand

Message

Abhishek Pandit-Subedi Sept. 17, 2019, 9:27 p.m. UTC
On a Realtek USB bluetooth device, I wanted a simple and consistent way
to put the device in reset during suspend (2 reasons: to save power and
disable BT as a wakeup source). Resetting it in the suspend callback
causes a detach and the resume callback is not called. Hence the changes
in this series to do the reset in suspend_noirq.

I looked into using PERSIST and reset on resume but those seem mainly
for misbehaving devices that reset themselves.

This patch series has been tested with Realtek BT hardware as well as
Intel BT (test procedure = disable as wake source, user suspend and
observe a detach + reattach on resume).



Abhishek Pandit-Subedi (2):
  usb: support suspend_noirq
  Bluetooth: btusb: Reset realtek devices on user suspend

 drivers/bluetooth/btusb.c | 26 ++++++++++++++++++
 drivers/usb/core/driver.c | 56 +++++++++++++++++++++++++++++++++++++++
 drivers/usb/core/usb.c    |  6 +++++
 include/linux/pm.h        |  8 ++++++
 include/linux/usb.h       |  3 +++
 5 files changed, 99 insertions(+)

Comments

Alan Stern Sept. 18, 2019, 2:23 p.m. UTC | #1
On Tue, 17 Sep 2019, Abhishek Pandit-Subedi wrote:

> On a Realtek USB bluetooth device, I wanted a simple and consistent way
> to put the device in reset during suspend (2 reasons: to save power and
> disable BT as a wakeup source). Resetting it in the suspend callback
> causes a detach and the resume callback is not called. Hence the changes
> in this series to do the reset in suspend_noirq.

What about people who _want_ BT to be a wakeup source?

Why does putting the device in reset save power?  That is, a suspended
device is very strictly limited in the amount of current it's allowed
to draw from the USB bus; why should it draw significantly less when it
is reset?

> I looked into using PERSIST and reset on resume but those seem mainly
> for misbehaving devices that reset themselves.

They are, but that doesn't mean you can't use them for other things 
too.

> This patch series has been tested with Realtek BT hardware as well as
> Intel BT (test procedure = disable as wake source, user suspend and
> observe a detach + reattach on resume).

This series really seems like overkill for a single kind of device.

Is there any way to turn off the device's BT radio during suspend (if
wakeup is disabled) and then turn it back on during resume?  Wouldn't 
that accomplish what you want just as well?

Alan Stern
Oliver Neukum Sept. 18, 2019, 2:41 p.m. UTC | #2
Am Dienstag, den 17.09.2019, 14:27 -0700 schrieb Abhishek Pandit-
Subedi:
> On a Realtek USB bluetooth device, I wanted a simple and consistent way
> to put the device in reset during suspend (2 reasons: to save power and

The device really uses less power if you reset it before suspendening
it?

> disable BT as a wakeup source). Resetting it in the suspend callback

Then do not enable it. Something is strange.

> causes a detach and the resume callback is not called. Hence the changes
> in this series to do the reset in suspend_noirq.
> 
> I looked into using PERSIST and reset on resume but those seem mainly
> for misbehaving devices that reset themselves.

No, not really. It is also for device that need to be reset if you use
the RESET_RESUME quirk. But that is on resume().
You could introduce a new flag. But the _noirq method is kind of
a hack, as USB really cannot operate without interrupts.

	Regards
		Oliver
Abhishek Pandit-Subedi Sept. 18, 2019, 5:19 p.m. UTC | #3
Sorry, last reply went out with HTML. Re-sending in plain text.

On Wed, Sep 18, 2019 at 7:23 AM Alan Stern <stern@rowland.harvard.edu> wrote:
>
> On Tue, 17 Sep 2019, Abhishek Pandit-Subedi wrote:
>
> > On a Realtek USB bluetooth device, I wanted a simple and consistent way
> > to put the device in reset during suspend (2 reasons: to save power and
> > disable BT as a wakeup source). Resetting it in the suspend callback
> > causes a detach and the resume callback is not called. Hence the changes
> > in this series to do the reset in suspend_noirq.
>
> What about people who _want_ BT to be a wakeup source?

When BT is enabled as a wakeup source, there is no reset.

> Why does putting the device in reset save power?  That is, a suspended
> device is very strictly limited in the amount of current it's allowed
> to draw from the USB bus; why should it draw significantly less when it
> is reset?

I don't know that it's significantly less (only that it's OFF). My
greater motivation is to make sure the bluetooth chip isn't
accumulating events while the host is turned off. Sorry, I should have
made that more clear in the cover letter.

When the host is off, it continues to accumulate events for the host
to process (packets from connected devices, LE advertisements, etc).
At some point, the firmware buffers fill up and no more events can be
stored. When the host is resumed later on, the firmware is in a bad
state and doesn't respond. I had originally just reset in ->resume but
then connected wireless devices wouldn't disconnect from the BT either
and I had trouble getting them to reconnect.

>
> > I looked into using PERSIST and reset on resume but those seem mainly
> > for misbehaving devices that reset themselves.
>
> They are, but that doesn't mean you can't use them for other things
> too.
>
> > This patch series has been tested with Realtek BT hardware as well as
> > Intel BT (test procedure = disable as wake source, user suspend and
> > observe a detach + reattach on resume).
>
> This series really seems like overkill for a single kind of device.
>
> Is there any way to turn off the device's BT radio during suspend (if
> wakeup is disabled) and then turn it back on during resume?  Wouldn't
> that accomplish what you want just as well?

Probably (but I couldn't find a way to do that). I want to prevent
bluetooth from waking up the host and to reliably be in a good state
when the host resumes. The reset logic I implemented causes the hci
device to disappear and reappear, which userspace seems to handle
gracefully.

> Alan Stern
>
Alan Stern Sept. 18, 2019, 6:51 p.m. UTC | #4
On Wed, 18 Sep 2019, Abhishek Pandit-Subedi wrote:

> Sorry, last reply went out with HTML. Re-sending in plain text.
> 
> On Wed, Sep 18, 2019 at 7:23 AM Alan Stern <stern@rowland.harvard.edu> wrote:
> >
> > On Tue, 17 Sep 2019, Abhishek Pandit-Subedi wrote:
> >
> > > On a Realtek USB bluetooth device, I wanted a simple and consistent way
> > > to put the device in reset during suspend (2 reasons: to save power and
> > > disable BT as a wakeup source). Resetting it in the suspend callback
> > > causes a detach and the resume callback is not called. Hence the changes
> > > in this series to do the reset in suspend_noirq.
> >
> > What about people who _want_ BT to be a wakeup source?
> 
> When BT is enabled as a wakeup source, there is no reset.
> 
> > Why does putting the device in reset save power?  That is, a suspended
> > device is very strictly limited in the amount of current it's allowed
> > to draw from the USB bus; why should it draw significantly less when it
> > is reset?
> 
> I don't know that it's significantly less (only that it's OFF). My
> greater motivation is to make sure the bluetooth chip isn't
> accumulating events while the host is turned off. Sorry, I should have
> made that more clear in the cover letter.
> 
> When the host is off, it continues to accumulate events for the host
> to process (packets from connected devices, LE advertisements, etc).
> At some point, the firmware buffers fill up and no more events can be
> stored. When the host is resumed later on, the firmware is in a bad
> state and doesn't respond. I had originally just reset in ->resume but
> then connected wireless devices wouldn't disconnect from the BT either
> and I had trouble getting them to reconnect.
> 
> >
> > > I looked into using PERSIST and reset on resume but those seem mainly
> > > for misbehaving devices that reset themselves.
> >
> > They are, but that doesn't mean you can't use them for other things
> > too.
> >
> > > This patch series has been tested with Realtek BT hardware as well as
> > > Intel BT (test procedure = disable as wake source, user suspend and
> > > observe a detach + reattach on resume).
> >
> > This series really seems like overkill for a single kind of device.
> >
> > Is there any way to turn off the device's BT radio during suspend (if
> > wakeup is disabled) and then turn it back on during resume?  Wouldn't
> > that accomplish what you want just as well?
> 
> Probably (but I couldn't find a way to do that).

There's no way to turn off the device's BT radio?  Then what happens 
when the user turns off Bluetooth from the wireless control panel?

>  I want to prevent
> bluetooth from waking up the host and to reliably be in a good state
> when the host resumes. The reset logic I implemented causes the hci
> device to disappear and reappear, which userspace seems to handle
> gracefully.

Have you tried out the persist/reset-on-resume approach?

Alan Stern
Abhishek Pandit-Subedi Sept. 26, 2019, 8:51 p.m. UTC | #5
On Wed, Sep 18, 2019 at 11:51 AM Alan Stern <stern@rowland.harvard.edu> wrote:
>
> On Wed, 18 Sep 2019, Abhishek Pandit-Subedi wrote:
>
> > Sorry, last reply went out with HTML. Re-sending in plain text.
> >
> > On Wed, Sep 18, 2019 at 7:23 AM Alan Stern <stern@rowland.harvard.edu> wrote:
> > >
> > > On Tue, 17 Sep 2019, Abhishek Pandit-Subedi wrote:
> > >
> > > > On a Realtek USB bluetooth device, I wanted a simple and consistent way
> > > > to put the device in reset during suspend (2 reasons: to save power and
> > > > disable BT as a wakeup source). Resetting it in the suspend callback
> > > > causes a detach and the resume callback is not called. Hence the changes
> > > > in this series to do the reset in suspend_noirq.
> > >
> > > What about people who _want_ BT to be a wakeup source?
> >
> > When BT is enabled as a wakeup source, there is no reset.
> >
> > > Why does putting the device in reset save power?  That is, a suspended
> > > device is very strictly limited in the amount of current it's allowed
> > > to draw from the USB bus; why should it draw significantly less when it
> > > is reset?
> >
> > I don't know that it's significantly less (only that it's OFF). My
> > greater motivation is to make sure the bluetooth chip isn't
> > accumulating events while the host is turned off. Sorry, I should have
> > made that more clear in the cover letter.
> >
> > When the host is off, it continues to accumulate events for the host
> > to process (packets from connected devices, LE advertisements, etc).
> > At some point, the firmware buffers fill up and no more events can be
> > stored. When the host is resumed later on, the firmware is in a bad
> > state and doesn't respond. I had originally just reset in ->resume but
> > then connected wireless devices wouldn't disconnect from the BT either
> > and I had trouble getting them to reconnect.
> >
> > >
> > > > I looked into using PERSIST and reset on resume but those seem mainly
> > > > for misbehaving devices that reset themselves.
> > >
> > > They are, but that doesn't mean you can't use them for other things
> > > too.
> > >
> > > > This patch series has been tested with Realtek BT hardware as well as
> > > > Intel BT (test procedure = disable as wake source, user suspend and
> > > > observe a detach + reattach on resume).
> > >
> > > This series really seems like overkill for a single kind of device.
> > >
> > > Is there any way to turn off the device's BT radio during suspend (if
> > > wakeup is disabled) and then turn it back on during resume?  Wouldn't
> > > that accomplish what you want just as well?
> >
> > Probably (but I couldn't find a way to do that).
>
> There's no way to turn off the device's BT radio?  Then what happens
> when the user turns off Bluetooth from the wireless control panel?

It looks like bluez invokes hci_dev_do_close. This gracefully clears
any packets in flight, clears any pending actions and disables the
device as a wakeup source (which for Realtek allows it to enter global
suspend). This is approximately what I was trying to achieve.

> >  I want to prevent
> > bluetooth from waking up the host and to reliably be in a good state
> > when the host resumes. The reset logic I implemented causes the hci
> > device to disappear and reappear, which userspace seems to handle
> > gracefully.
>
> Have you tried out the persist/reset-on-resume approach?
>
> Alan Stern
>

I think I'll abandon this patch series. The general sentiment seems to
be "don't do this" and it looks like closing the hci device is better
in my case.

Thanks for the feedback and pointing me this way.

Abhishek