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

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

> -----Original Message-----
> From: Luiz Augusto von Dentz <[email protected]>
> Sent: Wednesday, July 22, 2026 9:13 PM
> To: Devegowda, Chandrashekar <[email protected]>
> Cc: [email protected]; [email protected]; Srivatsa,
> Ravishankar <[email protected]>; Tumkur Narayan, Chethan
> <[email protected]>; K, Kiran <[email protected]>
> Subject: Re: [PATCH v4] Bluetooth: btintel_pcie: Add vendor_rst PCI sysfs for
> PLDR
> 
> Hi Chandru,
> 
> On Tue, Jul 21, 2026 at 9:22 PM Chandrashekar Devegowda
> <[email protected]> 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).
> > 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
> >
> > 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
> >
> > Changes in v2:
> >   - Added reset_type parameter to hdev->reset() callback (1/2)
> >   - vendor_rst sysfs used reset_type to select PLDR (2/2)
> >
> > Changes in v1:
> >   - Initial vendor_rst PCI sysfs implementation
> > drivers/bluetooth/btintel_pcie.c | 42
> +++++++++++++++++++++++++++++++-
> >  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"); }
> 
> Ok, so I assume this will be btintel_pcie only right? Not Bluetooth-wide? In
> that case you can call it pldr directly since it no longer need to generic and only
> applies to btintel_pcie driver.
> 

This is only for btintel_pcie driver currently keeping it as integer so that it can be scaled further for top-silent reset.


> > +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);
> > +       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
> >
> 
> 
> --
> Luiz Augusto von Dentz
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.