RE: [PATCH v4] Bluetooth: btintel_pcie: Add vendor_rst PCI sysfs for PLDR

"Devegowda, Chandrashekar" <[email protected]>
Newsgroups org.kernel.vger.linux-bluetooth,org.kernel.vger.linux-pci
Message-ID <IA3PR11MB90166865DEC5332EB1ABA891FCC02@IA3PR11MB9016.namprd11.prod.outlook.com>
Hi Bjorn,
     Thanks for the comments

> -----Original Message-----
> From: Bjorn Helgaas <[email protected]>
> Sent: Thursday, July 23, 2026 3:49 AM
> To: Devegowda, Chandrashekar <[email protected]>
> Cc: [email protected]; [email protected];
> [email protected]; Srivatsa, Ravishankar
> <[email protected]>; Tumkur Narayan, Chethan
> <[email protected]>; K, Kiran <[email protected]>; Alex
> Williamson <[email protected]>; [email protected]
> Subject: Re: [PATCH v4] Bluetooth: btintel_pcie: Add vendor_rst PCI sysfs for
> PLDR
> 
> [+cc Alex, linux-pci]
> 
> On Wed, Jul 22, 2026 at 06:51:57AM +0530, Chandrashekar Devegowda
> wrote:
> > Add a read-write sysfs entry at /sys/bus/pci/devices/<BDF>/vendor_rst
> > to allow userspace to trigger PLDR (Product Level Device Reset).
> 
> IMO there's no need to abbreviate "reset" as "rst".  I'd rather spell it out as
> "vendor_reset".
> 

Ack, will update in v5

> Several other drivers that add files in /sys/bus/pci/devices/ have
> documentation in Documentation/ABI/testing/sysfs-bus-pci-drivers-*.
> 
> It seems important to mention the fact that IIUC, this PLDR will release any
> driver attached to the wifi device that shares hardware with this bluetooth
> device, do the reset, and reprobe the wifi.
> 

Ack, will update the documentation and mention the impact on wifi.

> I guess this can't be integrated into the generic pci_reset_function() reachable
> via the sysfs 'reset' attribute because of the fact that it affects both the BT and
> the wifi device, which are different PCI functions.  But I cc'd Alex anyway since
> he's the real guru on resets.
> 
> FWIW, I learned a lot about the idiosyncrasies of these connected BT and wifi
> devices in this old conversation:
> https://lore.kernel.org/all/20250314101613.3682010-1-
> [email protected]
> 
> > 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 v4:
> >   - Rebased on latest bluetooth-next (6f55ad8fb0ac) to fix
> >     CI apply failure
> 
> v4: https://lore.kernel.org/all/20260722012158.813793-1-
> [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
> >   - Handle schedule_work() failure: release pci_dev_get refcount
> >     and clear RECOVERY_IN_PROGRESS flag
> >   - Fix remove ordering: device_remove_file before disable_work_sync
> 
> v3: https://lore.kernel.org/all/20260722001434.804931-1-
> [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/20260618085016.9173-1-
> [email protected]/
> 
> > Changes in v1:
> >   - Initial vendor_rst PCI sysfs implementation
> > drivers/bluetooth/btintel_pcie.c | 42
> +++++++++++++++++++++++++++++++-
> 
> v1: https://lore.kernel.org/all/20260612012832.2395034-1-
> [email protected]/
> 
> >  1 file changed, 41 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/bluetooth/btintel_pcie.c
> > b/drivers/bluetooth/btintel_pcie.c
> > index 2e28847263ab..a412ca7ff3ad 100644
> > --- a/drivers/bluetooth/btintel_pcie.c
> > +++ b/drivers/bluetooth/btintel_pcie.c
> > @@ -2781,7 +2781,10 @@ static void btintel_pcie_request_reset(struct
> btintel_pcie_data *data,
> >  	data->reset_type = type;
> >
> >  	pci_dev_get(data->pdev);
> > -	schedule_work(&data->reset_work);
> > +	if (!schedule_work(&data->reset_work)) {
> > +		pci_dev_put(data->pdev);
> > +		clear_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data-
> >flags);
> > +	}
> >  }
> >
> >  static void btintel_pcie_hci_reset(struct hci_dev *hdev) @@ -2791,6
> > +2794,36 @@ static void btintel_pcie_hci_reset(struct hci_dev *hdev)
> >  	btintel_pcie_request_reset(data, BTINTEL_PCIE_IOSF_PRR_FLR);  }
> >
> > +static ssize_t vendor_rst_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_rst_show(struct device *dev,
> > +			       struct device_attribute *attr, char *buf) {
> > +	return sysfs_emit(buf, "0 - PLDR\n"); }
> > +
> > +static DEVICE_ATTR_RW(vendor_rst);
> > +
> >  static void btintel_pcie_hw_error(struct hci_dev *hdev, u8 code)  {
> >  	struct btintel_pcie_dev_recovery *rec; @@ -3010,6 +3043,11 @@
> static
> > int btintel_pcie_probe(struct pci_dev *pdev,
> >  	if (err)
> >  		goto exit_error;
> >
> > +	err = device_create_file(&pdev->dev, &dev_attr_vendor_rst);
> 
> Can you avoid the manual device_create_file() by taking advantage of
> 23b6904442d0 ("driver core: add dev_groups to all drivers") and setting
> .dev_groups in your struct driver?
> 
> If you can, I think it would avoid a race between the device becoming visible in
> sysfs (and the uevent announcing that) and the addition of this sysfs attribute.
> 

Ack, will change to dev_groups in v5

> > +	if (err)
> > +		bt_dev_warn(data->hdev, "Failed to create vendor_rst sysfs
> (%d)",
> > +			    err);
> > +
> >  	bt_dev_dbg(data->hdev, "cnvi: 0x%8.8x cnvr: 0x%8.8x", data->cnvi,
> >  		   data->cnvr);
> >  	return 0;
> > @@ -3046,6 +3084,8 @@ static void btintel_pcie_remove(struct pci_dev
> *pdev)
> >  	disable_work_sync(&data->hwexp_work);
> >  	disable_work_sync(&data->fwtrigger_work);
> >
> > +	device_remove_file(&pdev->dev, &dev_attr_vendor_rst);
> > +
> >  	/* Cancel pending reset work. Skip only when remove() is called from
> >  	 * within the reset work itself (PLDR device_reprobe path) to avoid
> >  	 * deadlock. current_work() returns the work_struct of the caller if
> > --
> > 2.43.0
> >
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.