1818#include <linux/resource.h>
1919#include <linux/types.h>
2020
21+ #include "../../pci.h"
2122#include "pcie-designware.h"
2223
2324#define AMD_MDB_TLP_IR_STATUS_MISC 0x4C0
5657 * @slcr: MDB System Level Control and Status Register (SLCR) base
5758 * @intx_domain: INTx IRQ domain pointer
5859 * @mdb_domain: MDB IRQ domain pointer
60+ * @perst_gpio: GPIO descriptor for PERST# signal handling
5961 * @intx_irq: INTx IRQ interrupt number
6062 */
6163struct amd_mdb_pcie {
6264 struct dw_pcie pci ;
6365 void __iomem * slcr ;
6466 struct irq_domain * intx_domain ;
6567 struct irq_domain * mdb_domain ;
68+ struct gpio_desc * perst_gpio ;
6669 int intx_irq ;
6770};
6871
@@ -284,7 +287,7 @@ static int amd_mdb_pcie_init_irq_domains(struct amd_mdb_pcie *pcie,
284287 struct device_node * pcie_intc_node ;
285288 int err ;
286289
287- pcie_intc_node = of_get_next_child (node , NULL );
290+ pcie_intc_node = of_get_child_by_name (node , "interrupt-controller" );
288291 if (!pcie_intc_node ) {
289292 dev_err (dev , "No PCIe Intc node found\n" );
290293 return - ENODEV ;
@@ -402,6 +405,28 @@ static int amd_mdb_setup_irq(struct amd_mdb_pcie *pcie,
402405 return 0 ;
403406}
404407
408+ static int amd_mdb_parse_pcie_port (struct amd_mdb_pcie * pcie )
409+ {
410+ struct device * dev = pcie -> pci .dev ;
411+ struct device_node * pcie_port_node __maybe_unused ;
412+
413+ /*
414+ * This platform currently supports only one Root Port, so the loop
415+ * will execute only once.
416+ * TODO: Enhance the driver to handle multiple Root Ports in the future.
417+ */
418+ for_each_child_of_node_with_prefix (dev -> of_node , pcie_port_node , "pcie" ) {
419+ pcie -> perst_gpio = devm_fwnode_gpiod_get (dev , of_fwnode_handle (pcie_port_node ),
420+ "reset" , GPIOD_OUT_HIGH , NULL );
421+ if (IS_ERR (pcie -> perst_gpio ))
422+ return dev_err_probe (dev , PTR_ERR (pcie -> perst_gpio ),
423+ "Failed to request reset GPIO\n" );
424+ return 0 ;
425+ }
426+
427+ return - ENODEV ;
428+ }
429+
405430static int amd_mdb_add_pcie_port (struct amd_mdb_pcie * pcie ,
406431 struct platform_device * pdev )
407432{
@@ -426,6 +451,12 @@ static int amd_mdb_add_pcie_port(struct amd_mdb_pcie *pcie,
426451
427452 pp -> ops = & amd_mdb_pcie_host_ops ;
428453
454+ if (pcie -> perst_gpio ) {
455+ mdelay (PCIE_T_PVPERL_MS );
456+ gpiod_set_value_cansleep (pcie -> perst_gpio , 0 );
457+ mdelay (PCIE_RESET_CONFIG_WAIT_MS );
458+ }
459+
429460 err = dw_pcie_host_init (pp );
430461 if (err ) {
431462 dev_err (dev , "Failed to initialize host, err=%d\n" , err );
@@ -444,6 +475,7 @@ static int amd_mdb_pcie_probe(struct platform_device *pdev)
444475 struct device * dev = & pdev -> dev ;
445476 struct amd_mdb_pcie * pcie ;
446477 struct dw_pcie * pci ;
478+ int ret ;
447479
448480 pcie = devm_kzalloc (dev , sizeof (* pcie ), GFP_KERNEL );
449481 if (!pcie )
@@ -454,6 +486,24 @@ static int amd_mdb_pcie_probe(struct platform_device *pdev)
454486
455487 platform_set_drvdata (pdev , pcie );
456488
489+ ret = amd_mdb_parse_pcie_port (pcie );
490+ /*
491+ * If amd_mdb_parse_pcie_port returns -ENODEV, it indicates that the
492+ * PCIe Bridge node was not found in the device tree. This is not
493+ * considered a fatal error and will trigger a fallback where the
494+ * reset GPIO is acquired directly from the PCIe Host Bridge node.
495+ */
496+ if (ret ) {
497+ if (ret != - ENODEV )
498+ return ret ;
499+
500+ pcie -> perst_gpio = devm_gpiod_get_optional (dev , "reset" ,
501+ GPIOD_OUT_HIGH );
502+ if (IS_ERR (pcie -> perst_gpio ))
503+ return dev_err_probe (dev , PTR_ERR (pcie -> perst_gpio ),
504+ "Failed to request reset GPIO\n" );
505+ }
506+
457507 return amd_mdb_add_pcie_port (pcie , pdev );
458508}
459509
0 commit comments