From: Daniel Golle <daniel@makrotopia.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
Danilo Krummrich <dakr@kernel.org>,
driver-core@lists.linux.dev,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>, Andrew Lunn <andrew@lunn.ch>,
Vladimir Oltean <olteanv@gmail.com>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Miri Korenblit <miriam.rachel.korenblit@intel.com>,
linux-wireless@vger.kernel.org,
Marcel Holtmann <marcel@holtmann.org>,
Luiz Augusto von Dentz <luiz.dentz@gmail.com>,
linux-bluetooth@vger.kernel.org,
Hans de Goede <johannes.goede@oss.qualcomm.com>
Subject: [RFC PATCH 3/4] Bluetooth: hci_h5: use device_schedule_reprobe()
Date: Tue, 11 Aug 2026 01:49:31 +0100 [thread overview]
Message-ID: <anpxmyWKgUL6uYFN@makrotopia.org> (raw)
h5_btrtl_resume() open-codes a deferred re-probe for RTL devices that
lose their firmware state over suspend: it takes a module reference,
allocates a work item, and the work function calls device_reprobe()
and then ends with put_device(); kfree(); module_put(THIS_MODULE); in
module text. That final module_put() is racy: once the reference
count is decremented a concurrent rmmod can free the module text
before the work function's epilogue has finished executing. The work
also does not synchronize against shutdown or unbind, so a stale
re-probe could undo an administrative unbind or detach a device whose
->shutdown() callback has already run.
Convert to the new device_schedule_reprobe() helper, whose work
function is builtin text and which skips the re-probe when the device
was removed, shutdown reached it, or it is no longer bound to the
driver that scheduled the re-probe.
The old worker suppressed its error message for -EPROBE_DEFER; the
helper needs no equivalent because its attach half is
device_attach(), which folds probe deferral into the deferred-probe
machinery silently.
Behavioral changes:
- A pending re-probe no longer pins the module: rmmod with a re-probe
pending now succeeds immediately and the re-probe becomes a no-op,
instead of rmmod failing with EBUSY.
- A re-probe scheduled before a system shutdown or before an
administrative unbind no longer detaches and rebinds the device
afterwards.
- A re-probe racing the next suspend now detaches immediately while
the probe is deferred until the following resume by the
defer_all_probes machinery, instead of probing mid-suspend.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/bluetooth/hci_h5.c | 41 +++++---------------------------------
1 file changed, 5 insertions(+), 36 deletions(-)
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 60b90f1e11fc..3330f696fa3b 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -1047,46 +1047,15 @@ static int h5_btrtl_suspend(struct h5 *h5)
return 0;
}
-struct h5_btrtl_reprobe {
- struct device *dev;
- struct work_struct work;
-};
-
-static void h5_btrtl_reprobe_worker(struct work_struct *work)
-{
- struct h5_btrtl_reprobe *reprobe =
- container_of(work, struct h5_btrtl_reprobe, work);
- int ret;
-
- ret = device_reprobe(reprobe->dev);
- if (ret && ret != -EPROBE_DEFER)
- dev_err(reprobe->dev, "Reprobe error %d\n", ret);
-
- put_device(reprobe->dev);
- kfree(reprobe);
- module_put(THIS_MODULE);
-}
-
static int h5_btrtl_resume(struct h5 *h5)
{
- if (test_bit(H5_WAKEUP_DISABLE, &h5->flags)) {
- struct h5_btrtl_reprobe *reprobe;
-
- reprobe = kzalloc_obj(*reprobe);
- if (!reprobe)
- return -ENOMEM;
-
- __module_get(THIS_MODULE);
+ if (test_bit(H5_WAKEUP_DISABLE, &h5->flags))
+ return device_schedule_reprobe(&h5->hu->serdev->dev, 0);
- 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);
+ 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);
- }
+ if (test_bit(H5_HW_FLOW_CONTROL, &h5->flags))
+ serdev_device_set_flow_control(h5->hu->serdev, true);
return 0;
}
--
2.55.0
reply other threads:[~2026-08-11 0:49 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=anpxmyWKgUL6uYFN@makrotopia.org \
--to=daniel@makrotopia.org \
--cc=andrew@lunn.ch \
--cc=dakr@kernel.org \
--cc=davem@davemloft.net \
--cc=driver-core@lists.linux.dev \
--cc=edumazet@google.com \
--cc=gregkh@linuxfoundation.org \
--cc=horms@kernel.org \
--cc=johannes.goede@oss.qualcomm.com \
--cc=kuba@kernel.org \
--cc=linux-bluetooth@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=luiz.dentz@gmail.com \
--cc=marcel@holtmann.org \
--cc=miriam.rachel.korenblit@intel.com \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=rafael@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.