* [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
@ 2023-05-01 14:48 ` Frank Li
0 siblings, 0 replies; 14+ messages in thread
From: Frank Li @ 2023-05-01 14:48 UTC (permalink / raw)
To: Minghuan Lian, Mingkai Hu, Roy Zang, Lorenzo Pieralisi,
Rob Herring, Krzysztof Wilczyński, Bjorn Helgaas,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE, open list
Cc: imx
Layerscape has PME interrupt, which can be used as linkup notifier.
Set CFG_READY bit when linkup detected.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Change from v1 to v2
- pme -> PME
- irq -> IRQ
- update dev_info message according to Bjorn's suggestion
- remove '.' at error message
.../pci/controller/dwc/pci-layerscape-ep.c | 104 +++++++++++++++++-
1 file changed, 103 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index c640db60edc6..e974fbe3b6d8 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -18,6 +18,20 @@
#include "pcie-designware.h"
+#define PEX_PF0_CONFIG 0xC0014
+#define PEX_PF0_CFG_READY BIT(0)
+
+/* PEX PFa PCIE PME and message interrupt registers*/
+#define PEX_PF0_PME_MES_DR 0xC0020
+#define PEX_PF0_PME_MES_DR_LUD BIT(7)
+#define PEX_PF0_PME_MES_DR_LDD BIT(9)
+#define PEX_PF0_PME_MES_DR_HRD BIT(10)
+
+#define PEX_PF0_PME_MES_IER 0xC0028
+#define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
+#define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
+#define PEX_PF0_PME_MES_IER_HRDIE BIT(10)
+
#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
struct ls_pcie_ep_drvdata {
@@ -30,8 +44,88 @@ struct ls_pcie_ep {
struct dw_pcie *pci;
struct pci_epc_features *ls_epc;
const struct ls_pcie_ep_drvdata *drvdata;
+ bool big_endian;
+ int irq;
};
+static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset)
+{
+ struct dw_pcie *pci = pcie->pci;
+
+ if (pcie->big_endian)
+ return ioread32be(pci->dbi_base + offset);
+ else
+ return ioread32(pci->dbi_base + offset);
+}
+
+static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset,
+ u32 value)
+{
+ struct dw_pcie *pci = pcie->pci;
+
+ if (pcie->big_endian)
+ iowrite32be(value, pci->dbi_base + offset);
+ else
+ iowrite32(value, pci->dbi_base + offset);
+}
+
+static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
+{
+ struct ls_pcie_ep *pcie = (struct ls_pcie_ep *)dev_id;
+ struct dw_pcie *pci = pcie->pci;
+ u32 val, cfg;
+
+ val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR);
+ if (!val)
+ return IRQ_NONE;
+
+ if (val & PEX_PF0_PME_MES_DR_LUD) {
+ cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG);
+ cfg |= PEX_PF0_CFG_READY;
+ ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg);
+ dw_pcie_ep_linkup(&pci->ep);
+
+ dev_info(pci->dev, "Link up\n");
+ } else if (val & PEX_PF0_PME_MES_DR_LDD) {
+ dev_info(pci->dev, "Link down\n");
+ } else if (val & PEX_PF0_PME_MES_DR_HRD) {
+ dev_info(pci->dev, "Hot reset\n");
+ }
+
+ ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val);
+
+ return IRQ_HANDLED;
+}
+
+static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
+ struct platform_device *pdev)
+{
+ u32 val;
+ int ret;
+
+ pcie->irq = platform_get_irq_byname(pdev, "pme");
+ if (pcie->irq < 0) {
+ dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
+ return pcie->irq;
+ }
+
+ ret = devm_request_irq(&pdev->dev, pcie->irq,
+ ls_pcie_ep_event_handler, IRQF_SHARED,
+ pdev->name, pcie);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't register PCIe IRQ\n");
+ return ret;
+ }
+
+ /* Enable interrupts */
+ val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER);
+ val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE |
+ PEX_PF0_PME_MES_IER_LUDIE;
+ ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val);
+
+ return 0;
+}
+
static const struct pci_epc_features*
ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
{
@@ -125,6 +219,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
struct ls_pcie_ep *pcie;
struct pci_epc_features *ls_epc;
struct resource *dbi_base;
+ int ret;
pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
if (!pcie)
@@ -144,6 +239,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
pci->ops = pcie->drvdata->dw_pcie_ops;
ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
+ ls_epc->linkup_notifier = true;
pcie->pci = pci;
pcie->ls_epc = ls_epc;
@@ -155,9 +251,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
pci->ep.ops = &ls_pcie_ep_ops;
+ pcie->big_endian = of_property_read_bool(dev->of_node, "big-endian");
+
platform_set_drvdata(pdev, pcie);
- return dw_pcie_ep_init(&pci->ep);
+ ret = dw_pcie_ep_init(&pci->ep);
+ if (ret)
+ return ret;
+
+ return ls_pcie_ep_interrupt_init(pcie, pdev);
}
static struct platform_driver ls_pcie_ep_driver = {
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
@ 2023-05-01 14:48 ` Frank Li
0 siblings, 0 replies; 14+ messages in thread
From: Frank Li @ 2023-05-01 14:48 UTC (permalink / raw)
To: Minghuan Lian, Mingkai Hu, Roy Zang, Lorenzo Pieralisi,
Rob Herring, Krzysztof Wilczyński, Bjorn Helgaas,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE, open list
Cc: imx
Layerscape has PME interrupt, which can be used as linkup notifier.
Set CFG_READY bit when linkup detected.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Change from v1 to v2
- pme -> PME
- irq -> IRQ
- update dev_info message according to Bjorn's suggestion
- remove '.' at error message
.../pci/controller/dwc/pci-layerscape-ep.c | 104 +++++++++++++++++-
1 file changed, 103 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index c640db60edc6..e974fbe3b6d8 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -18,6 +18,20 @@
#include "pcie-designware.h"
+#define PEX_PF0_CONFIG 0xC0014
+#define PEX_PF0_CFG_READY BIT(0)
+
+/* PEX PFa PCIE PME and message interrupt registers*/
+#define PEX_PF0_PME_MES_DR 0xC0020
+#define PEX_PF0_PME_MES_DR_LUD BIT(7)
+#define PEX_PF0_PME_MES_DR_LDD BIT(9)
+#define PEX_PF0_PME_MES_DR_HRD BIT(10)
+
+#define PEX_PF0_PME_MES_IER 0xC0028
+#define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
+#define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
+#define PEX_PF0_PME_MES_IER_HRDIE BIT(10)
+
#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
struct ls_pcie_ep_drvdata {
@@ -30,8 +44,88 @@ struct ls_pcie_ep {
struct dw_pcie *pci;
struct pci_epc_features *ls_epc;
const struct ls_pcie_ep_drvdata *drvdata;
+ bool big_endian;
+ int irq;
};
+static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset)
+{
+ struct dw_pcie *pci = pcie->pci;
+
+ if (pcie->big_endian)
+ return ioread32be(pci->dbi_base + offset);
+ else
+ return ioread32(pci->dbi_base + offset);
+}
+
+static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset,
+ u32 value)
+{
+ struct dw_pcie *pci = pcie->pci;
+
+ if (pcie->big_endian)
+ iowrite32be(value, pci->dbi_base + offset);
+ else
+ iowrite32(value, pci->dbi_base + offset);
+}
+
+static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
+{
+ struct ls_pcie_ep *pcie = (struct ls_pcie_ep *)dev_id;
+ struct dw_pcie *pci = pcie->pci;
+ u32 val, cfg;
+
+ val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR);
+ if (!val)
+ return IRQ_NONE;
+
+ if (val & PEX_PF0_PME_MES_DR_LUD) {
+ cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG);
+ cfg |= PEX_PF0_CFG_READY;
+ ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg);
+ dw_pcie_ep_linkup(&pci->ep);
+
+ dev_info(pci->dev, "Link up\n");
+ } else if (val & PEX_PF0_PME_MES_DR_LDD) {
+ dev_info(pci->dev, "Link down\n");
+ } else if (val & PEX_PF0_PME_MES_DR_HRD) {
+ dev_info(pci->dev, "Hot reset\n");
+ }
+
+ ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val);
+
+ return IRQ_HANDLED;
+}
+
+static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
+ struct platform_device *pdev)
+{
+ u32 val;
+ int ret;
+
+ pcie->irq = platform_get_irq_byname(pdev, "pme");
+ if (pcie->irq < 0) {
+ dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
+ return pcie->irq;
+ }
+
+ ret = devm_request_irq(&pdev->dev, pcie->irq,
+ ls_pcie_ep_event_handler, IRQF_SHARED,
+ pdev->name, pcie);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't register PCIe IRQ\n");
+ return ret;
+ }
+
+ /* Enable interrupts */
+ val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER);
+ val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE |
+ PEX_PF0_PME_MES_IER_LUDIE;
+ ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val);
+
+ return 0;
+}
+
static const struct pci_epc_features*
ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
{
@@ -125,6 +219,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
struct ls_pcie_ep *pcie;
struct pci_epc_features *ls_epc;
struct resource *dbi_base;
+ int ret;
pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
if (!pcie)
@@ -144,6 +239,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
pci->ops = pcie->drvdata->dw_pcie_ops;
ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
+ ls_epc->linkup_notifier = true;
pcie->pci = pci;
pcie->ls_epc = ls_epc;
@@ -155,9 +251,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
pci->ep.ops = &ls_pcie_ep_ops;
+ pcie->big_endian = of_property_read_bool(dev->of_node, "big-endian");
+
platform_set_drvdata(pdev, pcie);
- return dw_pcie_ep_init(&pci->ep);
+ ret = dw_pcie_ep_init(&pci->ep);
+ if (ret)
+ return ret;
+
+ return ls_pcie_ep_interrupt_init(pcie, pdev);
}
static struct platform_driver ls_pcie_ep_driver = {
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
2023-05-01 14:48 ` Frank Li
(?)
@ 2023-05-06 7:58 ` Manivannan Sadhasivam
-1 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2023-05-06 7:58 UTC (permalink / raw)
To: Frank Li
Cc: Minghuan Lian, Mingkai Hu, Roy Zang, Lorenzo Pieralisi,
Rob Herring, Krzysztof Wilczyński, Bjorn Helgaas,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE, open list,
imx
On Mon, May 01, 2023 at 10:48:06AM -0400, Frank Li wrote:
> Layerscape has PME interrupt, which can be used as linkup notifier.
> Set CFG_READY bit when linkup detected.
Where are you setting this bit?
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> Change from v1 to v2
> - pme -> PME
> - irq -> IRQ
> - update dev_info message according to Bjorn's suggestion
> - remove '.' at error message
>
> .../pci/controller/dwc/pci-layerscape-ep.c | 104 +++++++++++++++++-
> 1 file changed, 103 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index c640db60edc6..e974fbe3b6d8 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -18,6 +18,20 @@
>
> #include "pcie-designware.h"
>
> +#define PEX_PF0_CONFIG 0xC0014
> +#define PEX_PF0_CFG_READY BIT(0)
> +
> +/* PEX PFa PCIE PME and message interrupt registers*/
> +#define PEX_PF0_PME_MES_DR 0xC0020
> +#define PEX_PF0_PME_MES_DR_LUD BIT(7)
> +#define PEX_PF0_PME_MES_DR_LDD BIT(9)
> +#define PEX_PF0_PME_MES_DR_HRD BIT(10)
> +
> +#define PEX_PF0_PME_MES_IER 0xC0028
> +#define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
> +#define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
> +#define PEX_PF0_PME_MES_IER_HRDIE BIT(10)
> +
> #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
>
> struct ls_pcie_ep_drvdata {
> @@ -30,8 +44,88 @@ struct ls_pcie_ep {
> struct dw_pcie *pci;
> struct pci_epc_features *ls_epc;
> const struct ls_pcie_ep_drvdata *drvdata;
> + bool big_endian;
> + int irq;
> };
>
> +static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset)
> +{
> + struct dw_pcie *pci = pcie->pci;
> +
> + if (pcie->big_endian)
> + return ioread32be(pci->dbi_base + offset);
> + else
> + return ioread32(pci->dbi_base + offset);
> +}
> +
> +static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset,
> + u32 value)
Above function argument could be wrapped within 80 columns.
> +{
> + struct dw_pcie *pci = pcie->pci;
> +
> + if (pcie->big_endian)
> + iowrite32be(value, pci->dbi_base + offset);
> + else
> + iowrite32(value, pci->dbi_base + offset);
> +}
> +
> +static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
> +{
> + struct ls_pcie_ep *pcie = (struct ls_pcie_ep *)dev_id;
No need to do explicit typecase for void pointer.
> + struct dw_pcie *pci = pcie->pci;
> + u32 val, cfg;
> +
> + val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR);
> + if (!val)
> + return IRQ_NONE;
> +
> + if (val & PEX_PF0_PME_MES_DR_LUD) {
> + cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG);
> + cfg |= PEX_PF0_CFG_READY;
> + ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg);
> + dw_pcie_ep_linkup(&pci->ep);
> +
> + dev_info(pci->dev, "Link up\n");
These messages could be demoted to dev_dbg() logs.
> + } else if (val & PEX_PF0_PME_MES_DR_LDD) {
> + dev_info(pci->dev, "Link down\n");
> + } else if (val & PEX_PF0_PME_MES_DR_HRD) {
> + dev_info(pci->dev, "Hot reset\n");
> + }
> +
> + ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val);
You should clear the interrupts before processing.
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
> + struct platform_device *pdev)
> +{
> + u32 val;
> + int ret;
> +
> + pcie->irq = platform_get_irq_byname(pdev, "pme");
> + if (pcie->irq < 0) {
> + dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
PME
> + return pcie->irq;
> + }
> +
> + ret = devm_request_irq(&pdev->dev, pcie->irq,
> + ls_pcie_ep_event_handler, IRQF_SHARED,
> + pdev->name, pcie);
Again, please wrap to fit the 80 column width.
> + if (ret) {
> + dev_err(&pdev->dev, "Can't register PCIe IRQ\n");
> + return ret;
> + }
> +
> + /* Enable interrupts */
> + val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER);
> + val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE |
> + PEX_PF0_PME_MES_IER_LUDIE;
> + ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val);
> +
> + return 0;
> +}
> +
> static const struct pci_epc_features*
> ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
> {
> @@ -125,6 +219,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> struct ls_pcie_ep *pcie;
> struct pci_epc_features *ls_epc;
> struct resource *dbi_base;
> + int ret;
>
> pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> if (!pcie)
> @@ -144,6 +239,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> pci->ops = pcie->drvdata->dw_pcie_ops;
>
> ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
> + ls_epc->linkup_notifier = true;
>
> pcie->pci = pci;
> pcie->ls_epc = ls_epc;
> @@ -155,9 +251,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
>
> pci->ep.ops = &ls_pcie_ep_ops;
>
> + pcie->big_endian = of_property_read_bool(dev->of_node, "big-endian");
> +
> platform_set_drvdata(pdev, pcie);
>
> - return dw_pcie_ep_init(&pci->ep);
> + ret = dw_pcie_ep_init(&pci->ep);
> + if (ret)
> + return ret;
Double space after return.
> +
> + return ls_pcie_ep_interrupt_init(pcie, pdev);
Double space after return.
- Mani
> }
>
> static struct platform_driver ls_pcie_ep_driver = {
> --
> 2.34.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
@ 2023-05-06 7:58 ` Manivannan Sadhasivam
0 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2023-05-06 7:58 UTC (permalink / raw)
To: Frank Li
Cc: Krzysztof Wilczyński, imx, Rob Herring,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Lorenzo Pieralisi,
open list, Minghuan Lian,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Roy Zang,
Bjorn Helgaas, open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
Mingkai Hu
On Mon, May 01, 2023 at 10:48:06AM -0400, Frank Li wrote:
> Layerscape has PME interrupt, which can be used as linkup notifier.
> Set CFG_READY bit when linkup detected.
Where are you setting this bit?
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> Change from v1 to v2
> - pme -> PME
> - irq -> IRQ
> - update dev_info message according to Bjorn's suggestion
> - remove '.' at error message
>
> .../pci/controller/dwc/pci-layerscape-ep.c | 104 +++++++++++++++++-
> 1 file changed, 103 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index c640db60edc6..e974fbe3b6d8 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -18,6 +18,20 @@
>
> #include "pcie-designware.h"
>
> +#define PEX_PF0_CONFIG 0xC0014
> +#define PEX_PF0_CFG_READY BIT(0)
> +
> +/* PEX PFa PCIE PME and message interrupt registers*/
> +#define PEX_PF0_PME_MES_DR 0xC0020
> +#define PEX_PF0_PME_MES_DR_LUD BIT(7)
> +#define PEX_PF0_PME_MES_DR_LDD BIT(9)
> +#define PEX_PF0_PME_MES_DR_HRD BIT(10)
> +
> +#define PEX_PF0_PME_MES_IER 0xC0028
> +#define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
> +#define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
> +#define PEX_PF0_PME_MES_IER_HRDIE BIT(10)
> +
> #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
>
> struct ls_pcie_ep_drvdata {
> @@ -30,8 +44,88 @@ struct ls_pcie_ep {
> struct dw_pcie *pci;
> struct pci_epc_features *ls_epc;
> const struct ls_pcie_ep_drvdata *drvdata;
> + bool big_endian;
> + int irq;
> };
>
> +static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset)
> +{
> + struct dw_pcie *pci = pcie->pci;
> +
> + if (pcie->big_endian)
> + return ioread32be(pci->dbi_base + offset);
> + else
> + return ioread32(pci->dbi_base + offset);
> +}
> +
> +static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset,
> + u32 value)
Above function argument could be wrapped within 80 columns.
> +{
> + struct dw_pcie *pci = pcie->pci;
> +
> + if (pcie->big_endian)
> + iowrite32be(value, pci->dbi_base + offset);
> + else
> + iowrite32(value, pci->dbi_base + offset);
> +}
> +
> +static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
> +{
> + struct ls_pcie_ep *pcie = (struct ls_pcie_ep *)dev_id;
No need to do explicit typecase for void pointer.
> + struct dw_pcie *pci = pcie->pci;
> + u32 val, cfg;
> +
> + val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR);
> + if (!val)
> + return IRQ_NONE;
> +
> + if (val & PEX_PF0_PME_MES_DR_LUD) {
> + cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG);
> + cfg |= PEX_PF0_CFG_READY;
> + ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg);
> + dw_pcie_ep_linkup(&pci->ep);
> +
> + dev_info(pci->dev, "Link up\n");
These messages could be demoted to dev_dbg() logs.
> + } else if (val & PEX_PF0_PME_MES_DR_LDD) {
> + dev_info(pci->dev, "Link down\n");
> + } else if (val & PEX_PF0_PME_MES_DR_HRD) {
> + dev_info(pci->dev, "Hot reset\n");
> + }
> +
> + ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val);
You should clear the interrupts before processing.
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
> + struct platform_device *pdev)
> +{
> + u32 val;
> + int ret;
> +
> + pcie->irq = platform_get_irq_byname(pdev, "pme");
> + if (pcie->irq < 0) {
> + dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
PME
> + return pcie->irq;
> + }
> +
> + ret = devm_request_irq(&pdev->dev, pcie->irq,
> + ls_pcie_ep_event_handler, IRQF_SHARED,
> + pdev->name, pcie);
Again, please wrap to fit the 80 column width.
> + if (ret) {
> + dev_err(&pdev->dev, "Can't register PCIe IRQ\n");
> + return ret;
> + }
> +
> + /* Enable interrupts */
> + val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER);
> + val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE |
> + PEX_PF0_PME_MES_IER_LUDIE;
> + ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val);
> +
> + return 0;
> +}
> +
> static const struct pci_epc_features*
> ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
> {
> @@ -125,6 +219,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> struct ls_pcie_ep *pcie;
> struct pci_epc_features *ls_epc;
> struct resource *dbi_base;
> + int ret;
>
> pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> if (!pcie)
> @@ -144,6 +239,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> pci->ops = pcie->drvdata->dw_pcie_ops;
>
> ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
> + ls_epc->linkup_notifier = true;
>
> pcie->pci = pci;
> pcie->ls_epc = ls_epc;
> @@ -155,9 +251,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
>
> pci->ep.ops = &ls_pcie_ep_ops;
>
> + pcie->big_endian = of_property_read_bool(dev->of_node, "big-endian");
> +
> platform_set_drvdata(pdev, pcie);
>
> - return dw_pcie_ep_init(&pci->ep);
> + ret = dw_pcie_ep_init(&pci->ep);
> + if (ret)
> + return ret;
Double space after return.
> +
> + return ls_pcie_ep_interrupt_init(pcie, pdev);
Double space after return.
- Mani
> }
>
> static struct platform_driver ls_pcie_ep_driver = {
> --
> 2.34.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
@ 2023-05-06 7:58 ` Manivannan Sadhasivam
0 siblings, 0 replies; 14+ messages in thread
From: Manivannan Sadhasivam @ 2023-05-06 7:58 UTC (permalink / raw)
To: Frank Li
Cc: Minghuan Lian, Mingkai Hu, Roy Zang, Lorenzo Pieralisi,
Rob Herring, Krzysztof Wilczyński, Bjorn Helgaas,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE, open list,
imx
On Mon, May 01, 2023 at 10:48:06AM -0400, Frank Li wrote:
> Layerscape has PME interrupt, which can be used as linkup notifier.
> Set CFG_READY bit when linkup detected.
Where are you setting this bit?
>
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> Change from v1 to v2
> - pme -> PME
> - irq -> IRQ
> - update dev_info message according to Bjorn's suggestion
> - remove '.' at error message
>
> .../pci/controller/dwc/pci-layerscape-ep.c | 104 +++++++++++++++++-
> 1 file changed, 103 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index c640db60edc6..e974fbe3b6d8 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -18,6 +18,20 @@
>
> #include "pcie-designware.h"
>
> +#define PEX_PF0_CONFIG 0xC0014
> +#define PEX_PF0_CFG_READY BIT(0)
> +
> +/* PEX PFa PCIE PME and message interrupt registers*/
> +#define PEX_PF0_PME_MES_DR 0xC0020
> +#define PEX_PF0_PME_MES_DR_LUD BIT(7)
> +#define PEX_PF0_PME_MES_DR_LDD BIT(9)
> +#define PEX_PF0_PME_MES_DR_HRD BIT(10)
> +
> +#define PEX_PF0_PME_MES_IER 0xC0028
> +#define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
> +#define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
> +#define PEX_PF0_PME_MES_IER_HRDIE BIT(10)
> +
> #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
>
> struct ls_pcie_ep_drvdata {
> @@ -30,8 +44,88 @@ struct ls_pcie_ep {
> struct dw_pcie *pci;
> struct pci_epc_features *ls_epc;
> const struct ls_pcie_ep_drvdata *drvdata;
> + bool big_endian;
> + int irq;
> };
>
> +static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset)
> +{
> + struct dw_pcie *pci = pcie->pci;
> +
> + if (pcie->big_endian)
> + return ioread32be(pci->dbi_base + offset);
> + else
> + return ioread32(pci->dbi_base + offset);
> +}
> +
> +static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset,
> + u32 value)
Above function argument could be wrapped within 80 columns.
> +{
> + struct dw_pcie *pci = pcie->pci;
> +
> + if (pcie->big_endian)
> + iowrite32be(value, pci->dbi_base + offset);
> + else
> + iowrite32(value, pci->dbi_base + offset);
> +}
> +
> +static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
> +{
> + struct ls_pcie_ep *pcie = (struct ls_pcie_ep *)dev_id;
No need to do explicit typecase for void pointer.
> + struct dw_pcie *pci = pcie->pci;
> + u32 val, cfg;
> +
> + val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR);
> + if (!val)
> + return IRQ_NONE;
> +
> + if (val & PEX_PF0_PME_MES_DR_LUD) {
> + cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG);
> + cfg |= PEX_PF0_CFG_READY;
> + ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg);
> + dw_pcie_ep_linkup(&pci->ep);
> +
> + dev_info(pci->dev, "Link up\n");
These messages could be demoted to dev_dbg() logs.
> + } else if (val & PEX_PF0_PME_MES_DR_LDD) {
> + dev_info(pci->dev, "Link down\n");
> + } else if (val & PEX_PF0_PME_MES_DR_HRD) {
> + dev_info(pci->dev, "Hot reset\n");
> + }
> +
> + ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val);
You should clear the interrupts before processing.
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
> + struct platform_device *pdev)
> +{
> + u32 val;
> + int ret;
> +
> + pcie->irq = platform_get_irq_byname(pdev, "pme");
> + if (pcie->irq < 0) {
> + dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
PME
> + return pcie->irq;
> + }
> +
> + ret = devm_request_irq(&pdev->dev, pcie->irq,
> + ls_pcie_ep_event_handler, IRQF_SHARED,
> + pdev->name, pcie);
Again, please wrap to fit the 80 column width.
> + if (ret) {
> + dev_err(&pdev->dev, "Can't register PCIe IRQ\n");
> + return ret;
> + }
> +
> + /* Enable interrupts */
> + val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER);
> + val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE |
> + PEX_PF0_PME_MES_IER_LUDIE;
> + ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val);
> +
> + return 0;
> +}
> +
> static const struct pci_epc_features*
> ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
> {
> @@ -125,6 +219,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> struct ls_pcie_ep *pcie;
> struct pci_epc_features *ls_epc;
> struct resource *dbi_base;
> + int ret;
>
> pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> if (!pcie)
> @@ -144,6 +239,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> pci->ops = pcie->drvdata->dw_pcie_ops;
>
> ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
> + ls_epc->linkup_notifier = true;
>
> pcie->pci = pci;
> pcie->ls_epc = ls_epc;
> @@ -155,9 +251,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
>
> pci->ep.ops = &ls_pcie_ep_ops;
>
> + pcie->big_endian = of_property_read_bool(dev->of_node, "big-endian");
> +
> platform_set_drvdata(pdev, pcie);
>
> - return dw_pcie_ep_init(&pci->ep);
> + ret = dw_pcie_ep_init(&pci->ep);
> + if (ret)
> + return ret;
Double space after return.
> +
> + return ls_pcie_ep_interrupt_init(pcie, pdev);
Double space after return.
- Mani
> }
>
> static struct platform_driver ls_pcie_ep_driver = {
> --
> 2.34.1
>
--
மணிவண்ணன் சதாசிவம்
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
2023-05-06 7:58 ` Manivannan Sadhasivam
@ 2023-05-08 13:31 ` Frank Li
-1 siblings, 0 replies; 14+ messages in thread
From: Frank Li @ 2023-05-08 13:31 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: M.H. Lian, Mingkai Hu, Roy Zang, Lorenzo Pieralisi, Rob Herring,
Krzysztof Wilczyński, Bjorn Helgaas,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE, open list,
imx
> -----Original Message-----
> From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> Sent: Saturday, May 6, 2023 2:59 AM
> To: Frank Li <frank.li@nxp.com>
> Cc: M.H. Lian <minghuan.lian@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; Roy Zang <roy.zang@nxp.com>; Lorenzo Pieralisi
> <lpieralisi@kernel.org>; Rob Herring <robh@kernel.org>; Krzysztof
> Wilczyński <kw@linux.com>; Bjorn Helgaas <bhelgaas@google.com>; open
> list:PCI DRIVER FOR FREESCALE LAYERSCAPE <linuxppc-dev@lists.ozlabs.org>;
> open list:PCI DRIVER FOR FREESCALE LAYERSCAPE <linux-
> pci@vger.kernel.org>; moderated list:PCI DRIVER FOR FREESCALE
> LAYERSCAPE <linux-arm-kernel@lists.infradead.org>; open list <linux-
> kernel@vger.kernel.org>; imx@lists.linux.dev
> Subject: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup
> notifier support
>
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
>
>
> On Mon, May 01, 2023 at 10:48:06AM -0400, Frank Li wrote:
> > Layerscape has PME interrupt, which can be used as linkup notifier.
> > Set CFG_READY bit when linkup detected.
>
> Where are you setting this bit?
>
> >
> > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> > Signed-off-by: Frank Li <Frank.Li@nxp.com>
> > ---
> > Change from v1 to v2
> > - pme -> PME
> > - irq -> IRQ
> > - update dev_info message according to Bjorn's suggestion
> > - remove '.' at error message
> >
> > .../pci/controller/dwc/pci-layerscape-ep.c | 104 +++++++++++++++++-
> > 1 file changed, 103 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > index c640db60edc6..e974fbe3b6d8 100644
> > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > @@ -18,6 +18,20 @@
> >
> > #include "pcie-designware.h"
> >
> > +#define PEX_PF0_CONFIG 0xC0014
> > +#define PEX_PF0_CFG_READY BIT(0)
> > +
> > +/* PEX PFa PCIE PME and message interrupt registers*/
> > +#define PEX_PF0_PME_MES_DR 0xC0020
> > +#define PEX_PF0_PME_MES_DR_LUD BIT(7)
> > +#define PEX_PF0_PME_MES_DR_LDD BIT(9)
> > +#define PEX_PF0_PME_MES_DR_HRD BIT(10)
> > +
> > +#define PEX_PF0_PME_MES_IER 0xC0028
> > +#define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
> > +#define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
> > +#define PEX_PF0_PME_MES_IER_HRDIE BIT(10)
> > +
> > #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
> >
> > struct ls_pcie_ep_drvdata {
> > @@ -30,8 +44,88 @@ struct ls_pcie_ep {
> > struct dw_pcie *pci;
> > struct pci_epc_features *ls_epc;
> > const struct ls_pcie_ep_drvdata *drvdata;
> > + bool big_endian;
> > + int irq;
> > };
> >
> > +static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset)
> > +{
> > + struct dw_pcie *pci = pcie->pci;
> > +
> > + if (pcie->big_endian)
> > + return ioread32be(pci->dbi_base + offset);
> > + else
> > + return ioread32(pci->dbi_base + offset);
> > +}
> > +
> > +static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset,
> > + u32 value)
>
> Above function argument could be wrapped within 80 columns.
>
> > +{
> > + struct dw_pcie *pci = pcie->pci;
> > +
> > + if (pcie->big_endian)
> > + iowrite32be(value, pci->dbi_base + offset);
> > + else
> > + iowrite32(value, pci->dbi_base + offset);
> > +}
> > +
> > +static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
> > +{
> > + struct ls_pcie_ep *pcie = (struct ls_pcie_ep *)dev_id;
>
> No need to do explicit typecase for void pointer.
>
> > + struct dw_pcie *pci = pcie->pci;
> > + u32 val, cfg;
> > +
> > + val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR);
> > + if (!val)
> > + return IRQ_NONE;
> > +
> > + if (val & PEX_PF0_PME_MES_DR_LUD) {
> > + cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG);
> > + cfg |= PEX_PF0_CFG_READY;
> > + ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg);
> > + dw_pcie_ep_linkup(&pci->ep);
> > +
> > + dev_info(pci->dev, "Link up\n");
>
> These messages could be demoted to dev_dbg() logs.
>
> > + } else if (val & PEX_PF0_PME_MES_DR_LDD) {
> > + dev_info(pci->dev, "Link down\n");
> > + } else if (val & PEX_PF0_PME_MES_DR_HRD) {
> > + dev_info(pci->dev, "Hot reset\n");
> > + }
> > +
> > + ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val);
>
> You should clear the interrupts before processing.
>
> > +
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
> > + struct platform_device *pdev)
> > +{
> > + u32 val;
> > + int ret;
> > +
> > + pcie->irq = platform_get_irq_byname(pdev, "pme");
> > + if (pcie->irq < 0) {
> > + dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
>
> PME
Here should be dts property `pme`, suppose should match
platform_get_irq_byname(pdev, "pme");
>
> > + return pcie->irq;
> > + }
> > +
> > + ret = devm_request_irq(&pdev->dev, pcie->irq,
> > + ls_pcie_ep_event_handler, IRQF_SHARED,
> > + pdev->name, pcie);
>
> Again, please wrap to fit the 80 column width.
>
> > + if (ret) {
> > + dev_err(&pdev->dev, "Can't register PCIe IRQ\n");
> > + return ret;
> > + }
> > +
> > + /* Enable interrupts */
> > + val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER);
> > + val |= PEX_PF0_PME_MES_IER_LDDIE |
> PEX_PF0_PME_MES_IER_HRDIE |
> > + PEX_PF0_PME_MES_IER_LUDIE;
> > + ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val);
> > +
> > + return 0;
> > +}
> > +
> > static const struct pci_epc_features*
> > ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
> > {
> > @@ -125,6 +219,7 @@ static int __init ls_pcie_ep_probe(struct
> platform_device *pdev)
> > struct ls_pcie_ep *pcie;
> > struct pci_epc_features *ls_epc;
> > struct resource *dbi_base;
> > + int ret;
> >
> > pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> > if (!pcie)
> > @@ -144,6 +239,7 @@ static int __init ls_pcie_ep_probe(struct
> platform_device *pdev)
> > pci->ops = pcie->drvdata->dw_pcie_ops;
> >
> > ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
> > + ls_epc->linkup_notifier = true;
> >
> > pcie->pci = pci;
> > pcie->ls_epc = ls_epc;
> > @@ -155,9 +251,15 @@ static int __init ls_pcie_ep_probe(struct
> platform_device *pdev)
> >
> > pci->ep.ops = &ls_pcie_ep_ops;
> >
> > + pcie->big_endian = of_property_read_bool(dev->of_node, "big-
> endian");
> > +
> > platform_set_drvdata(pdev, pcie);
> >
> > - return dw_pcie_ep_init(&pci->ep);
> > + ret = dw_pcie_ep_init(&pci->ep);
> > + if (ret)
> > + return ret;
>
> Double space after return.
>
> > +
> > + return ls_pcie_ep_interrupt_init(pcie, pdev);
>
> Double space after return.
>
> - Mani
>
> > }
> >
> > static struct platform_driver ls_pcie_ep_driver = {
> > --
> > 2.34.1
> >
>
> --
> மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
@ 2023-05-08 13:31 ` Frank Li
0 siblings, 0 replies; 14+ messages in thread
From: Frank Li @ 2023-05-08 13:31 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Krzysztof Wilczyński, imx, Rob Herring,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Lorenzo Pieralisi,
open list, M.H. Lian,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Roy Zang,
Bjorn Helgaas, open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
Mingkai Hu
> -----Original Message-----
> From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> Sent: Saturday, May 6, 2023 2:59 AM
> To: Frank Li <frank.li@nxp.com>
> Cc: M.H. Lian <minghuan.lian@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; Roy Zang <roy.zang@nxp.com>; Lorenzo Pieralisi
> <lpieralisi@kernel.org>; Rob Herring <robh@kernel.org>; Krzysztof
> Wilczyński <kw@linux.com>; Bjorn Helgaas <bhelgaas@google.com>; open
> list:PCI DRIVER FOR FREESCALE LAYERSCAPE <linuxppc-dev@lists.ozlabs.org>;
> open list:PCI DRIVER FOR FREESCALE LAYERSCAPE <linux-
> pci@vger.kernel.org>; moderated list:PCI DRIVER FOR FREESCALE
> LAYERSCAPE <linux-arm-kernel@lists.infradead.org>; open list <linux-
> kernel@vger.kernel.org>; imx@lists.linux.dev
> Subject: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup
> notifier support
>
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
>
>
> On Mon, May 01, 2023 at 10:48:06AM -0400, Frank Li wrote:
> > Layerscape has PME interrupt, which can be used as linkup notifier.
> > Set CFG_READY bit when linkup detected.
>
> Where are you setting this bit?
>
> >
> > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> > Signed-off-by: Frank Li <Frank.Li@nxp.com>
> > ---
> > Change from v1 to v2
> > - pme -> PME
> > - irq -> IRQ
> > - update dev_info message according to Bjorn's suggestion
> > - remove '.' at error message
> >
> > .../pci/controller/dwc/pci-layerscape-ep.c | 104 +++++++++++++++++-
> > 1 file changed, 103 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > index c640db60edc6..e974fbe3b6d8 100644
> > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > @@ -18,6 +18,20 @@
> >
> > #include "pcie-designware.h"
> >
> > +#define PEX_PF0_CONFIG 0xC0014
> > +#define PEX_PF0_CFG_READY BIT(0)
> > +
> > +/* PEX PFa PCIE PME and message interrupt registers*/
> > +#define PEX_PF0_PME_MES_DR 0xC0020
> > +#define PEX_PF0_PME_MES_DR_LUD BIT(7)
> > +#define PEX_PF0_PME_MES_DR_LDD BIT(9)
> > +#define PEX_PF0_PME_MES_DR_HRD BIT(10)
> > +
> > +#define PEX_PF0_PME_MES_IER 0xC0028
> > +#define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
> > +#define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
> > +#define PEX_PF0_PME_MES_IER_HRDIE BIT(10)
> > +
> > #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
> >
> > struct ls_pcie_ep_drvdata {
> > @@ -30,8 +44,88 @@ struct ls_pcie_ep {
> > struct dw_pcie *pci;
> > struct pci_epc_features *ls_epc;
> > const struct ls_pcie_ep_drvdata *drvdata;
> > + bool big_endian;
> > + int irq;
> > };
> >
> > +static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset)
> > +{
> > + struct dw_pcie *pci = pcie->pci;
> > +
> > + if (pcie->big_endian)
> > + return ioread32be(pci->dbi_base + offset);
> > + else
> > + return ioread32(pci->dbi_base + offset);
> > +}
> > +
> > +static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset,
> > + u32 value)
>
> Above function argument could be wrapped within 80 columns.
>
> > +{
> > + struct dw_pcie *pci = pcie->pci;
> > +
> > + if (pcie->big_endian)
> > + iowrite32be(value, pci->dbi_base + offset);
> > + else
> > + iowrite32(value, pci->dbi_base + offset);
> > +}
> > +
> > +static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
> > +{
> > + struct ls_pcie_ep *pcie = (struct ls_pcie_ep *)dev_id;
>
> No need to do explicit typecase for void pointer.
>
> > + struct dw_pcie *pci = pcie->pci;
> > + u32 val, cfg;
> > +
> > + val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR);
> > + if (!val)
> > + return IRQ_NONE;
> > +
> > + if (val & PEX_PF0_PME_MES_DR_LUD) {
> > + cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG);
> > + cfg |= PEX_PF0_CFG_READY;
> > + ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg);
> > + dw_pcie_ep_linkup(&pci->ep);
> > +
> > + dev_info(pci->dev, "Link up\n");
>
> These messages could be demoted to dev_dbg() logs.
>
> > + } else if (val & PEX_PF0_PME_MES_DR_LDD) {
> > + dev_info(pci->dev, "Link down\n");
> > + } else if (val & PEX_PF0_PME_MES_DR_HRD) {
> > + dev_info(pci->dev, "Hot reset\n");
> > + }
> > +
> > + ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val);
>
> You should clear the interrupts before processing.
>
> > +
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
> > + struct platform_device *pdev)
> > +{
> > + u32 val;
> > + int ret;
> > +
> > + pcie->irq = platform_get_irq_byname(pdev, "pme");
> > + if (pcie->irq < 0) {
> > + dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
>
> PME
Here should be dts property `pme`, suppose should match
platform_get_irq_byname(pdev, "pme");
>
> > + return pcie->irq;
> > + }
> > +
> > + ret = devm_request_irq(&pdev->dev, pcie->irq,
> > + ls_pcie_ep_event_handler, IRQF_SHARED,
> > + pdev->name, pcie);
>
> Again, please wrap to fit the 80 column width.
>
> > + if (ret) {
> > + dev_err(&pdev->dev, "Can't register PCIe IRQ\n");
> > + return ret;
> > + }
> > +
> > + /* Enable interrupts */
> > + val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER);
> > + val |= PEX_PF0_PME_MES_IER_LDDIE |
> PEX_PF0_PME_MES_IER_HRDIE |
> > + PEX_PF0_PME_MES_IER_LUDIE;
> > + ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val);
> > +
> > + return 0;
> > +}
> > +
> > static const struct pci_epc_features*
> > ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
> > {
> > @@ -125,6 +219,7 @@ static int __init ls_pcie_ep_probe(struct
> platform_device *pdev)
> > struct ls_pcie_ep *pcie;
> > struct pci_epc_features *ls_epc;
> > struct resource *dbi_base;
> > + int ret;
> >
> > pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> > if (!pcie)
> > @@ -144,6 +239,7 @@ static int __init ls_pcie_ep_probe(struct
> platform_device *pdev)
> > pci->ops = pcie->drvdata->dw_pcie_ops;
> >
> > ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
> > + ls_epc->linkup_notifier = true;
> >
> > pcie->pci = pci;
> > pcie->ls_epc = ls_epc;
> > @@ -155,9 +251,15 @@ static int __init ls_pcie_ep_probe(struct
> platform_device *pdev)
> >
> > pci->ep.ops = &ls_pcie_ep_ops;
> >
> > + pcie->big_endian = of_property_read_bool(dev->of_node, "big-
> endian");
> > +
> > platform_set_drvdata(pdev, pcie);
> >
> > - return dw_pcie_ep_init(&pci->ep);
> > + ret = dw_pcie_ep_init(&pci->ep);
> > + if (ret)
> > + return ret;
>
> Double space after return.
>
> > +
> > + return ls_pcie_ep_interrupt_init(pcie, pdev);
>
> Double space after return.
>
> - Mani
>
> > }
> >
> > static struct platform_driver ls_pcie_ep_driver = {
> > --
> > 2.34.1
> >
>
> --
> மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
2023-05-08 13:31 ` Frank Li
@ 2023-05-08 21:31 ` Bjorn Helgaas
-1 siblings, 0 replies; 14+ messages in thread
From: Bjorn Helgaas @ 2023-05-08 21:31 UTC (permalink / raw)
To: Frank Li
Cc: Manivannan Sadhasivam, Krzysztof Wilczyński, imx,
Rob Herring, open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
Lorenzo Pieralisi, open list, M.H. Lian,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Roy Zang,
Bjorn Helgaas, open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
Mingkai Hu
On Mon, May 08, 2023 at 01:31:26PM +0000, Frank Li wrote:
> > -----Original Message-----
> > From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > Sent: Saturday, May 6, 2023 2:59 AM
> > To: Frank Li <frank.li@nxp.com>
> > Cc: M.H. Lian <minghuan.lian@nxp.com>; Mingkai Hu
> > <mingkai.hu@nxp.com>; Roy Zang <roy.zang@nxp.com>; Lorenzo Pieralisi
> > <lpieralisi@kernel.org>; Rob Herring <robh@kernel.org>; Krzysztof
> > Wilczyński <kw@linux.com>; Bjorn Helgaas <bhelgaas@google.com>; open
> > list:PCI DRIVER FOR FREESCALE LAYERSCAPE <linuxppc-dev@lists.ozlabs.org>;
> > open list:PCI DRIVER FOR FREESCALE LAYERSCAPE <linux-
> > pci@vger.kernel.org>; moderated list:PCI DRIVER FOR FREESCALE
> > LAYERSCAPE <linux-arm-kernel@lists.infradead.org>; open list <linux-
> > kernel@vger.kernel.org>; imx@lists.linux.dev
> > Subject: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup
> > notifier support
All these quoted headers are redundant clutter since we've already
seen them when Manivannan sent his comments. It would be nice if your
mailer could be configured to omit them.
> > > +static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
> > > + struct platform_device *pdev)
> > > +{
> > > + u32 val;
> > > + int ret;
> > > +
> > > + pcie->irq = platform_get_irq_byname(pdev, "pme");
> > > + if (pcie->irq < 0) {
> > > + dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
> >
> > PME
>
> Here should be dts property `pme`, suppose should match
> platform_get_irq_byname(pdev, "pme");
You can also edit out all the other context and questions if you're
not responding to them.
There were a lot of other comments that were useful but are not
relevant to this reply.
Bjorn
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
@ 2023-05-08 21:31 ` Bjorn Helgaas
0 siblings, 0 replies; 14+ messages in thread
From: Bjorn Helgaas @ 2023-05-08 21:31 UTC (permalink / raw)
To: Frank Li
Cc: Krzysztof Wilczyński, imx,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Lorenzo Pieralisi,
open list, M.H. Lian, Mingkai Hu, Manivannan Sadhasivam,
Bjorn Helgaas, Roy Zang,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Rob Herring,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE
On Mon, May 08, 2023 at 01:31:26PM +0000, Frank Li wrote:
> > -----Original Message-----
> > From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > Sent: Saturday, May 6, 2023 2:59 AM
> > To: Frank Li <frank.li@nxp.com>
> > Cc: M.H. Lian <minghuan.lian@nxp.com>; Mingkai Hu
> > <mingkai.hu@nxp.com>; Roy Zang <roy.zang@nxp.com>; Lorenzo Pieralisi
> > <lpieralisi@kernel.org>; Rob Herring <robh@kernel.org>; Krzysztof
> > Wilczyński <kw@linux.com>; Bjorn Helgaas <bhelgaas@google.com>; open
> > list:PCI DRIVER FOR FREESCALE LAYERSCAPE <linuxppc-dev@lists.ozlabs.org>;
> > open list:PCI DRIVER FOR FREESCALE LAYERSCAPE <linux-
> > pci@vger.kernel.org>; moderated list:PCI DRIVER FOR FREESCALE
> > LAYERSCAPE <linux-arm-kernel@lists.infradead.org>; open list <linux-
> > kernel@vger.kernel.org>; imx@lists.linux.dev
> > Subject: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup
> > notifier support
All these quoted headers are redundant clutter since we've already
seen them when Manivannan sent his comments. It would be nice if your
mailer could be configured to omit them.
> > > +static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
> > > + struct platform_device *pdev)
> > > +{
> > > + u32 val;
> > > + int ret;
> > > +
> > > + pcie->irq = platform_get_irq_byname(pdev, "pme");
> > > + if (pcie->irq < 0) {
> > > + dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
> >
> > PME
>
> Here should be dts property `pme`, suppose should match
> platform_get_irq_byname(pdev, "pme");
You can also edit out all the other context and questions if you're
not responding to them.
There were a lot of other comments that were useful but are not
relevant to this reply.
Bjorn
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
2023-05-08 21:31 ` Bjorn Helgaas
@ 2023-05-08 21:45 ` Frank Li
-1 siblings, 0 replies; 14+ messages in thread
From: Frank Li @ 2023-05-08 21:45 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Manivannan Sadhasivam, Krzysztof Wilczyński, imx,
Rob Herring, open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
Lorenzo Pieralisi, open list, M.H. Lian,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Roy Zang,
Bjorn Helgaas, open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
Mingkai Hu
> > > Subject: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint
> linkup
> > > notifier support
>
> All these quoted headers are redundant clutter since we've already
> seen them when Manivannan sent his comments. It would be nice if your
> mailer could be configured to omit them.
Our email client quite stupid.
>
> > > > +static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
> > > > + struct platform_device *pdev)
> > > > +{
> > > > + u32 val;
> > > > + int ret;
> > > > +
> > > > + pcie->irq = platform_get_irq_byname(pdev, "pme");
> > > > + if (pcie->irq < 0) {
> > > > + dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
> > >
> > > PME
> >
> > Here should be dts property `pme`, suppose should match
> > platform_get_irq_byname(pdev, "pme");
>
> You can also edit out all the other context and questions if you're
> not responding to them.
>
> There were a lot of other comments that were useful but are not
> relevant to this reply.
Okay, I found I mess up patch version number.
>
> Bjorn
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
@ 2023-05-08 21:45 ` Frank Li
0 siblings, 0 replies; 14+ messages in thread
From: Frank Li @ 2023-05-08 21:45 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Krzysztof Wilczyński, imx,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Lorenzo Pieralisi,
open list, M.H. Lian, Mingkai Hu, Manivannan Sadhasivam,
Bjorn Helgaas, Roy Zang,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Rob Herring,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE
> > > Subject: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint
> linkup
> > > notifier support
>
> All these quoted headers are redundant clutter since we've already
> seen them when Manivannan sent his comments. It would be nice if your
> mailer could be configured to omit them.
Our email client quite stupid.
>
> > > > +static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
> > > > + struct platform_device *pdev)
> > > > +{
> > > > + u32 val;
> > > > + int ret;
> > > > +
> > > > + pcie->irq = platform_get_irq_byname(pdev, "pme");
> > > > + if (pcie->irq < 0) {
> > > > + dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
> > >
> > > PME
> >
> > Here should be dts property `pme`, suppose should match
> > platform_get_irq_byname(pdev, "pme");
>
> You can also edit out all the other context and questions if you're
> not responding to them.
>
> There were a lot of other comments that were useful but are not
> relevant to this reply.
Okay, I found I mess up patch version number.
>
> Bjorn
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
2023-05-08 21:45 ` Frank Li
@ 2023-05-09 19:44 ` Bjorn Helgaas
-1 siblings, 0 replies; 14+ messages in thread
From: Bjorn Helgaas @ 2023-05-09 19:44 UTC (permalink / raw)
To: Frank Li
Cc: Krzysztof Wilczyński, imx,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Lorenzo Pieralisi,
open list, M.H. Lian, Mingkai Hu, Manivannan Sadhasivam,
Bjorn Helgaas, Roy Zang,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Rob Herring,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE
On Mon, May 08, 2023 at 09:45:59PM +0000, Frank Li wrote:
> > > > Subject: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint
> > linkup
> > > > notifier support
> >
> > All these quoted headers are redundant clutter since we've already
> > seen them when Manivannan sent his comments. It would be nice if your
> > mailer could be configured to omit them.
>
> Our email client quite stupid.
Yeah, sometimes those are really hard to work around.
Bjorn
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
@ 2023-05-09 19:44 ` Bjorn Helgaas
0 siblings, 0 replies; 14+ messages in thread
From: Bjorn Helgaas @ 2023-05-09 19:44 UTC (permalink / raw)
To: Frank Li
Cc: Krzysztof Wilczyński, imx,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Lorenzo Pieralisi,
open list, M.H. Lian,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
Manivannan Sadhasivam, Bjorn Helgaas, Roy Zang,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE, Rob Herring,
Mingkai Hu
On Mon, May 08, 2023 at 09:45:59PM +0000, Frank Li wrote:
> > > > Subject: [EXT] Re: [PATCH v2 1/1] PCI: layerscape: Add the endpoint
> > linkup
> > > > notifier support
> >
> > All these quoted headers are redundant clutter since we've already
> > seen them when Manivannan sent his comments. It would be nice if your
> > mailer could be configured to omit them.
>
> Our email client quite stupid.
Yeah, sometimes those are really hard to work around.
Bjorn
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support
@ 2023-05-08 13:45 Frank Li
0 siblings, 0 replies; 14+ messages in thread
From: Frank Li @ 2023-05-08 13:45 UTC (permalink / raw)
To: Minghuan Lian, Mingkai Hu, Roy Zang, Lorenzo Pieralisi,
Rob Herring, Krzysztof Wilczyński, Bjorn Helgaas,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
open list:PCI DRIVER FOR FREESCALE LAYERSCAPE,
moderated list:PCI DRIVER FOR FREESCALE LAYERSCAPE, open list
Cc: imx
Layerscape has PME interrupt, which can be used as linkup notifier.
Set CFG_READY bit of PEX_PF0_CONFIG to enable accesses from root complex
when linkup detected.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
.../pci/controller/dwc/pci-layerscape-ep.c | 102 +++++++++++++++++-
1 file changed, 101 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index c640db60edc6..1a431a9be91e 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -18,6 +18,20 @@
#include "pcie-designware.h"
+#define PEX_PF0_CONFIG 0xC0014
+#define PEX_PF0_CFG_READY BIT(0)
+
+/* PEX PFa PCIE PME and message interrupt registers*/
+#define PEX_PF0_PME_MES_DR 0xC0020
+#define PEX_PF0_PME_MES_DR_LUD BIT(7)
+#define PEX_PF0_PME_MES_DR_LDD BIT(9)
+#define PEX_PF0_PME_MES_DR_HRD BIT(10)
+
+#define PEX_PF0_PME_MES_IER 0xC0028
+#define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
+#define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
+#define PEX_PF0_PME_MES_IER_HRDIE BIT(10)
+
#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
struct ls_pcie_ep_drvdata {
@@ -30,8 +44,86 @@ struct ls_pcie_ep {
struct dw_pcie *pci;
struct pci_epc_features *ls_epc;
const struct ls_pcie_ep_drvdata *drvdata;
+ bool big_endian;
+ int irq;
};
+static u32 ls_lut_readl(struct ls_pcie_ep *pcie, u32 offset)
+{
+ struct dw_pcie *pci = pcie->pci;
+
+ if (pcie->big_endian)
+ return ioread32be(pci->dbi_base + offset);
+ else
+ return ioread32(pci->dbi_base + offset);
+}
+
+static void ls_lut_writel(struct ls_pcie_ep *pcie, u32 offset, u32 value)
+{
+ struct dw_pcie *pci = pcie->pci;
+
+ if (pcie->big_endian)
+ iowrite32be(value, pci->dbi_base + offset);
+ else
+ iowrite32(value, pci->dbi_base + offset);
+}
+
+static irqreturn_t ls_pcie_ep_event_handler(int irq, void *dev_id)
+{
+ struct ls_pcie_ep *pcie = dev_id;
+ struct dw_pcie *pci = pcie->pci;
+ u32 val, cfg;
+
+ val = ls_lut_readl(pcie, PEX_PF0_PME_MES_DR);
+ ls_lut_writel(pcie, PEX_PF0_PME_MES_DR, val);
+
+ if (!val)
+ return IRQ_NONE;
+
+ if (val & PEX_PF0_PME_MES_DR_LUD) {
+ cfg = ls_lut_readl(pcie, PEX_PF0_CONFIG);
+ cfg |= PEX_PF0_CFG_READY;
+ ls_lut_writel(pcie, PEX_PF0_CONFIG, cfg);
+ dw_pcie_ep_linkup(&pci->ep);
+
+ dev_dbg(pci->dev, "Link up\n");
+ } else if (val & PEX_PF0_PME_MES_DR_LDD) {
+ dev_dbg(pci->dev, "Link down\n");
+ } else if (val & PEX_PF0_PME_MES_DR_HRD) {
+ dev_dbg(pci->dev, "Hot reset\n");
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int ls_pcie_ep_interrupt_init(struct ls_pcie_ep *pcie,
+ struct platform_device *pdev)
+{
+ u32 val;
+ int ret;
+
+ pcie->irq = platform_get_irq_byname(pdev, "pme");
+ if (pcie->irq < 0) {
+ dev_err(&pdev->dev, "Can't get 'pme' IRQ\n");
+ return pcie->irq;
+ }
+
+ ret = devm_request_irq(&pdev->dev, pcie->irq, ls_pcie_ep_event_handler,
+ IRQF_SHARED, pdev->name, pcie);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't register PCIe IRQ\n");
+ return ret;
+ }
+
+ /* Enable interrupts */
+ val = ls_lut_readl(pcie, PEX_PF0_PME_MES_IER);
+ val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE |
+ PEX_PF0_PME_MES_IER_LUDIE;
+ ls_lut_writel(pcie, PEX_PF0_PME_MES_IER, val);
+
+ return 0;
+}
+
static const struct pci_epc_features*
ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
{
@@ -125,6 +217,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
struct ls_pcie_ep *pcie;
struct pci_epc_features *ls_epc;
struct resource *dbi_base;
+ int ret;
pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
if (!pcie)
@@ -144,6 +237,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
pci->ops = pcie->drvdata->dw_pcie_ops;
ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
+ ls_epc->linkup_notifier = true;
pcie->pci = pci;
pcie->ls_epc = ls_epc;
@@ -155,9 +249,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
pci->ep.ops = &ls_pcie_ep_ops;
+ pcie->big_endian = of_property_read_bool(dev->of_node, "big-endian");
+
platform_set_drvdata(pdev, pcie);
- return dw_pcie_ep_init(&pci->ep);
+ ret = dw_pcie_ep_init(&pci->ep);
+ if (ret)
+ return ret;
+
+ return ls_pcie_ep_interrupt_init(pcie, pdev);
}
static struct platform_driver ls_pcie_ep_driver = {
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2023-05-09 19:45 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-01 14:48 [PATCH v2 1/1] PCI: layerscape: Add the endpoint linkup notifier support Frank Li
2023-05-01 14:48 ` Frank Li
2023-05-06 7:58 ` Manivannan Sadhasivam
2023-05-06 7:58 ` Manivannan Sadhasivam
2023-05-06 7:58 ` Manivannan Sadhasivam
2023-05-08 13:31 ` [EXT] " Frank Li
2023-05-08 13:31 ` Frank Li
2023-05-08 21:31 ` Bjorn Helgaas
2023-05-08 21:31 ` Bjorn Helgaas
2023-05-08 21:45 ` Frank Li
2023-05-08 21:45 ` Frank Li
2023-05-09 19:44 ` Bjorn Helgaas
2023-05-09 19:44 ` Bjorn Helgaas
2023-05-08 13:45 Frank Li
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.