diff options
| author | Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> | 2026-07-27 10:51:02 +0530 |
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2026-08-07 15:38:31 -0400 |
| commit | 39bbe7b7386fb3cdbb1c02a240e40d45f1435778 (patch) | |
| tree | e0676da6a6bd02dc4f1c23a9c8b6e3d971faa729 | |
| parent | 80718e2e0fbce54d57146564455f123daebfe11a (diff) | |
| download | linux-next-39bbe7b7386fb3cdbb1c02a240e40d45f1435778.tar.gz linux-next-39bbe7b7386fb3cdbb1c02a240e40d45f1435778.zip | |
Bluetooth: btintel_pcie: Add vendor_reset PCI sysfs for PLDR
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 <chandrashekar.devegowda@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
| -rw-r--r-- | Documentation/ABI/testing/sysfs-bus-pci-drivers-btintel_pcie | 15 | ||||
| -rw-r--r-- | MAINTAINERS | 1 | ||||
| -rw-r--r-- | drivers/bluetooth/btintel_pcie.c | 38 |
3 files changed, 54 insertions, 0 deletions
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 +Date: 22-Jul-2026 +KernelVersion: 6.17 +Contact: linux-bluetooth@vger.kernel.org +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. + + 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 08e43bc09735..891c064a881b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4719,6 +4719,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); + + return count; +} + +static ssize_t vendor_reset_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "0 - PLDR\n"); +} + +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 |
