[PATCH 1/2] PCI: dwc: Add LTSSM tracing support to debugfs
Manivannan Sadhasivam
mani at kernel.org
Wed Jan 7 04:40:14 PST 2026
On Wed, Jan 07, 2026 at 02:42:38PM +0530, Krishna Chaitanya Chundru wrote:
>
>
> On 1/6/2026 2:48 PM, Shawn Lin wrote:
> > Some platforms may provide LTSSM trace functionality, recording historical
> > LTSSM state transition information. This is very useful for debugging, such
> > as when certain devices cannot be recognized. Add an ltssm_trace operation
> > node in debugfs for platform which could provide these information to show
> > the LTSSM history.
> >
> > Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> > ---
> > .../controller/dwc/pcie-designware-debugfs.c | 44 +++++++++++++++++++
> > drivers/pci/controller/dwc/pcie-designware.h | 6 +++
> > 2 files changed, 50 insertions(+)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-debugfs.c b/drivers/pci/controller/dwc/pcie-designware-debugfs.c
> > index df98fee69892..569e8e078ef2 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-debugfs.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-debugfs.c
> > @@ -511,6 +511,38 @@ static int ltssm_status_open(struct inode *inode, struct file *file)
> > return single_open(file, ltssm_status_show, inode->i_private);
> > }
> > +static struct dw_pcie_ltssm_history *dw_pcie_ltssm_trace(struct dw_pcie *pci)
> > +{
> > + if (pci->ops && pci->ops->ltssm_trace)
> > + return pci->ops->ltssm_trace(pci);
> > +
> > + return NULL;
> > +}
> > +
> > +static int ltssm_trace_show(struct seq_file *s, void *v)
> > +{
> > + struct dw_pcie *pci = s->private;
> > + struct dw_pcie_ltssm_history *history;
> > + enum dw_pcie_ltssm val;
> > + u32 loop;
> > +
> > + history = dw_pcie_ltssm_trace(pci);
> > + if (!history)
> > + return 0;
> > +
> > + for (loop = 0; loop < history->count; loop++) {
> > + val = history->states[loop];
> > + seq_printf(s, "%s (0x%02x)\n", ltssm_status_string(val), val);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int ltssm_trace_open(struct inode *inode, struct file *file)
> > +{
> > + return single_open(file, ltssm_trace_show, inode->i_private);
> > +}
> > +
> > #define dwc_debugfs_create(name) \
> > debugfs_create_file(#name, 0644, rasdes_debug, pci, \
> > &dbg_ ## name ## _fops)
> > @@ -552,6 +584,11 @@ static const struct file_operations dwc_pcie_ltssm_status_ops = {
> > .read = seq_read,
> > };
> > +static const struct file_operations dwc_pcie_ltssm_trace_ops = {
> > + .open = ltssm_trace_open,
> > + .read = seq_read,
> > +};
> > +
> > static void dwc_pcie_rasdes_debugfs_deinit(struct dw_pcie *pci)
> > {
> > struct dwc_pcie_rasdes_info *rinfo = pci->debugfs->rasdes_info;
> > @@ -644,6 +681,12 @@ static void dwc_pcie_ltssm_debugfs_init(struct dw_pcie *pci, struct dentry *dir)
> > &dwc_pcie_ltssm_status_ops);
> > }
> > +static void dwc_pcie_ltssm_trace_debugfs_init(struct dw_pcie *pci, struct dentry *dir)
> > +{
> > + debugfs_create_file("ltssm_trace", 0444, dir, pci,
> > + &dwc_pcie_ltssm_trace_ops);
> Can we have this as the sysfs, so that if there is some issue in production
> devices where debugfs is not available,
> we can use this to see LTSSM state figure out the issue.
'figure out' means 'debug'. If you want to debug an issue, you need to enable
debugfs. You should not introduce random sysfs ABI for debug interfaces.
- Mani
>
> - Krishna Chaitanya.
> > +}
> > +
> > static int dw_pcie_ptm_check_capability(void *drvdata)
> > {
> > struct dw_pcie *pci = drvdata;
> > @@ -922,6 +965,7 @@ void dwc_pcie_debugfs_init(struct dw_pcie *pci, enum dw_pcie_device_mode mode)
> > err);
> > dwc_pcie_ltssm_debugfs_init(pci, dir);
> > + dwc_pcie_ltssm_trace_debugfs_init(pci, dir);
> > pci->mode = mode;
> > pci->ptm_debugfs = pcie_ptm_create_debugfs(pci->dev, pci,
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > index 5cd27f5739f1..0df18995b7fe 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > @@ -395,6 +395,11 @@ enum dw_pcie_ltssm {
> > DW_PCIE_LTSSM_UNKNOWN = 0xFFFFFFFF,
> > };
> > +struct dw_pcie_ltssm_history {
> > + enum dw_pcie_ltssm *states;
> > + u32 count;
> > +};
> > +
> > struct dw_pcie_ob_atu_cfg {
> > int index;
> > int type;
> > @@ -499,6 +504,7 @@ struct dw_pcie_ops {
> > size_t size, u32 val);
> > bool (*link_up)(struct dw_pcie *pcie);
> > enum dw_pcie_ltssm (*get_ltssm)(struct dw_pcie *pcie);
> > + struct dw_pcie_ltssm_history * (*ltssm_trace)(struct dw_pcie *pcie);
> > int (*start_link)(struct dw_pcie *pcie);
> > void (*stop_link)(struct dw_pcie *pcie);
> > int (*assert_perst)(struct dw_pcie *pcie, bool assert);
>
--
மணிவண்ணன் சதாசிவம்
More information about the Linux-rockchip
mailing list