Re: [PATCH v6] Bluetooth: btintel_pcie: Add vendor_reset PCI sysfs for PLDR
Luiz Augusto von Dentz <[email protected]> Thu, 30 Jul 2026 11:36:17 -0400
| Newsgroups | org.kernel.vger.linux-bluetooth,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <CABBYNZ+=otGcq6H0WOJddPf13gnAArJCFCEH_P3JoUuArZUOLw@mail.gmail.com> |
Hi Chandru, On Mon, Jul 27, 2026 at 5:57 PM Alex Williamson <[email protected]> wrote: > > On Mon, 27 Jul 2026 10:51:02 +0530 > Chandrashekar Devegowda <[email protected]> wrote: > > > Add a read-write sysfs entry at /sys/bus/pci/devices/<BDF>/vendor_reset > > to allow userspace to trigger PLDR (Product Level Device Reset). > > Reading the attribute displays supported reset types. Writing > > integer 0 triggers PLDR. Any other input is rejected with > > -EINVAL and a warning log. > > > > Signed-off-by: Chandrashekar Devegowda <[email protected]> > > --- > > Changes in v6: > > - Fixed .driver.dev_groups -> .dev_groups on struct pci_driver > > (__pci_register_driver overwrites .driver.dev_groups with .dev_groups) > > - Removed unrelated schedule_work() failure handling from > > btintel_pcie_request_reset() that caused CI context mismatch > > > > Changes in v5: > > - Renamed sysfs from vendor_rst to vendor_reset (reviewer feedback) > > - Switched from device_create_file() to driver dev_groups for > > automatic race-free sysfs lifecycle management > > - Added ABI doc at Documentation/ABI/testing/sysfs-bus-pci-drivers-btintel_pcie > > - Added WiFi impact description to ABI documentation > > - Added MAINTAINERS F: entry for ABI doc > > - v5: https://lore.kernel.org/all/[email protected]/ > > > > Changes in v4: > > - Rebased on latest bluetooth-next to fix CI apply failure > > - v4: https://lore.kernel.org/all/[email protected]/ > > > > Changes in v3: > > - Dropped reset_type parameter approach from hdev->reset() > > - Directly call btintel_pcie_request_reset() instead of manual > > flag manipulation and schedule_work() > > - Accept only integer 0 for PLDR trigger > > - v3: https://lore.kernel.org/all/[email protected]/ > > > > Changes in v2: > > - Added reset_type parameter to hdev->reset() callback (1/2) > > - vendor_rst sysfs used reset_type to select PLDR (2/2) > > - v2: https://lore.kernel.org/all/[email protected]/ > > > > Changes in v1: > > - Initial implementation > > - v1: https://lore.kernel.org/all/[email protected]/ > > .../sysfs-bus-pci-drivers-btintel_pcie | 15 ++++++++ > > MAINTAINERS | 1 + > > drivers/bluetooth/btintel_pcie.c | 38 +++++++++++++++++++ > > 3 files changed, 54 insertions(+) > > create mode 100644 Documentation/ABI/testing/sysfs-bus-pci-drivers-btintel_pcie > > > > diff --git a/Documentation/ABI/testing/sysfs-bus-pci-drivers-btintel_pcie b/Documentation/ABI/testing/sysfs-bus-pci-drivers-btintel_pcie > > new file mode 100644 > > index 000000000000..cceec6ac96bc > > --- /dev/null > > +++ b/Documentation/ABI/testing/sysfs-bus-pci-drivers-btintel_pcie > > @@ -0,0 +1,15 @@ > > +What: /sys/bus/pci/devices/<BDF>/vendor_reset > > Nit, domain is present too, not just BDF. > > > +Date: 22-Jul-2026 > > +KernelVersion: 6.17 This needs fixing. > Kernel 6.17 was 10 months ago. > > > +Contact: [email protected] > > +Description: This read-write attribute allows userspace to trigger a > > + Product Level Device Reset (PLDR) on Intel PCIe Bluetooth > > + controllers. Reading the attribute displays the supported > > + reset type. Writing integer 0 triggers PLDR. Any other > > + input is rejected with -EINVAL. > > This is opposite of /sys/bus/pci/devices/<BDF>/reset for no apparent > reason and seems like it infringes on the namespace of sysfs-bus-pci. Meaning this should write 1 to reset, right? > > + > > + PLDR resets the entire on-chip platform shared between > > + Bluetooth and WiFi. This means any driver attached to > > + the WiFi device that shares hardware with this Bluetooth > > + device will be released, the platform will be reset, and > > + both the Bluetooth and WiFi devices will be re-probed. > > diff --git a/MAINTAINERS b/MAINTAINERS > > index eb8cdcc76324..39d390f1ceb4 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -4625,6 +4625,7 @@ S: Supported > > W: http://www.bluez.org/ > > T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git > > T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git > > +F: Documentation/ABI/testing/sysfs-bus-pci-drivers-btintel_pcie > > F: Documentation/devicetree/bindings/net/bluetooth/ > > F: drivers/bluetooth/ > > > > diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c > > index ef42b8d11d4d..005c77a4f5eb 100644 > > --- a/drivers/bluetooth/btintel_pcie.c > > +++ b/drivers/bluetooth/btintel_pcie.c > > @@ -2790,6 +2790,43 @@ static void btintel_pcie_hci_reset(struct hci_dev *hdev) > > btintel_pcie_request_reset(data, BTINTEL_PCIE_IOSF_PRR_FLR); > > } > > > > +static ssize_t vendor_reset_store(struct device *dev, > > + struct device_attribute *attr, > > + const char *buf, size_t count) > > +{ > > + unsigned int val; > > + struct pci_dev *pdev = to_pci_dev(dev); > > + struct btintel_pcie_data *data = pci_get_drvdata(pdev); > > + > > + if (!data || !data->hdev) > > + return -ENODEV; > > + > > + if (kstrtouint(buf, 10, &val) || val != 0) { > > + bt_dev_warn(data->hdev, "PLDR rejected: invalid input"); > > + return -EINVAL; > > + } > > + > > + bt_dev_info(data->hdev, "PLDR triggered via sysfs"); > > + btintel_pcie_request_reset(data, BTINTEL_PCIE_IOSF_PRR_PLDR); > > This is pretty scary on its own, scanning for specific wifi device IDs, > finding the first match and releasing the driver for it while holding > pci_lock_rescan_remove(). So an attribute on one device that unbinds > the driver for another device (or worse, maybe reset it anyway if the > SKUs are out of sync), and the reset happens asynchronously at some > point in the future. If the wifi device happens to be in use by > vfio-pci, that delay is unbounded as it relies on a userspace driver or > VM to release the device. @ChandraShekar Please clarify. I guess we have no option since there is no parent device to abstract the combo Wifi/BT design. This should only be used when both Wifi and Bluetooth need a reset, so at that point they shouldn't be operational. That said, maybe we should check if control has been handed over to a VM, in which case we probably need to reject resetting it. > > + > > + return count; > > +} > > + > > +static ssize_t vendor_reset_show(struct device *dev, > > + struct device_attribute *attr, char *buf) > > +{ > > + return sysfs_emit(buf, "0 - PLDR\n"); > > It seems like this is implying an enumerable list of resets, but the > API is committing to zero/-EINVAL. The string also isn't very sysfs > compliant. Thanks, I guess you will need to explain what a 'compliant' sysfs read would be; is this supposed to just return the current value (e.g. "0")? > Alex > > > +} > > + > > +static DEVICE_ATTR_RW(vendor_reset); > > + > > +static struct attribute *btintel_pcie_attrs[] = { > > + &dev_attr_vendor_reset.attr, > > + NULL, > > +}; > > + > > +ATTRIBUTE_GROUPS(btintel_pcie); > > + > > static void btintel_pcie_hw_error(struct hci_dev *hdev, u8 code) > > { > > struct btintel_pcie_dev_recovery *rec; > > @@ -3250,6 +3287,7 @@ static struct pci_driver btintel_pcie_driver = { > > .probe = btintel_pcie_probe, > > .remove = btintel_pcie_remove, > > .driver.pm = pm_sleep_ptr(&btintel_pcie_pm_ops), > > + .dev_groups = btintel_pcie_groups, > > #ifdef CONFIG_DEV_COREDUMP > > .driver.coredump = btintel_pcie_coredump > > #endif > -- Luiz Augusto von Dentz