Skip to content

Commit 9b2e9ba

Browse files
committed
Merge branch 'pci/controller/dwc-qcom'
- Parse PERST# from all PCIe bridge nodes for future platforms that will have PERST# in Switch Downstream Ports as well as in Root Ports (Manivannan Sadhasivam) - Rename qcom PERST# assert/deassert helpers, e.g., qcom_ep_reset_assert(), to avoid confusion with Endpoint interfaces (Manivannan Sadhasivam) * pci/controller/dwc-qcom: PCI: qcom: Rename PERST# assert/deassert helpers for uniformity PCI: qcom: Parse PERST# from all PCIe bridge nodes # Conflicts: # drivers/pci/controller/dwc/pcie-qcom.c
2 parents d375df1 + 8d8db7d commit 9b2e9ba

1 file changed

Lines changed: 95 additions & 27 deletions

File tree

drivers/pci/controller/dwc/pcie-qcom.c

Lines changed: 95 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,15 @@ struct qcom_pcie_cfg {
261261
bool no_l0s;
262262
};
263263

264+
struct qcom_pcie_perst {
265+
struct list_head list;
266+
struct gpio_desc *desc;
267+
};
268+
264269
struct qcom_pcie_port {
265270
struct list_head list;
266-
struct gpio_desc *reset;
267271
struct phy *phy;
272+
struct list_head perst;
268273
};
269274

270275
struct qcom_pcie {
@@ -283,27 +288,30 @@ struct qcom_pcie {
283288

284289
#define to_qcom_pcie(x) dev_get_drvdata((x)->dev)
285290

286-
static void qcom_perst_assert(struct qcom_pcie *pcie, bool assert)
291+
static void __qcom_pcie_perst_assert(struct qcom_pcie *pcie, bool assert)
287292
{
293+
struct qcom_pcie_perst *perst;
288294
struct qcom_pcie_port *port;
289295
int val = assert ? 1 : 0;
290296

291-
list_for_each_entry(port, &pcie->ports, list)
292-
gpiod_set_value_cansleep(port->reset, val);
297+
list_for_each_entry(port, &pcie->ports, list) {
298+
list_for_each_entry(perst, &port->perst, list)
299+
gpiod_set_value_cansleep(perst->desc, val);
300+
}
293301

294302
usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
295303
}
296304

297-
static void qcom_ep_reset_assert(struct qcom_pcie *pcie)
305+
static void qcom_pcie_perst_assert(struct qcom_pcie *pcie)
298306
{
299-
qcom_perst_assert(pcie, true);
307+
__qcom_pcie_perst_assert(pcie, true);
300308
}
301309

302-
static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)
310+
static void qcom_pcie_perst_deassert(struct qcom_pcie *pcie)
303311
{
304-
/* Ensure that PERST has been asserted for at least 100 ms */
312+
/* Ensure that PERST# has been asserted for at least 100 ms */
305313
msleep(PCIE_T_PVPERL_MS);
306-
qcom_perst_assert(pcie, false);
314+
__qcom_pcie_perst_assert(pcie, false);
307315
}
308316

309317
static int qcom_pcie_start_link(struct dw_pcie *pci)
@@ -1282,7 +1290,7 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
12821290
struct qcom_pcie *pcie = to_qcom_pcie(pci);
12831291
int ret;
12841292

1285-
qcom_ep_reset_assert(pcie);
1293+
qcom_pcie_perst_assert(pcie);
12861294

12871295
ret = pcie->cfg->ops->init(pcie);
12881296
if (ret)
@@ -1309,7 +1317,7 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
13091317
dw_pcie_remove_capability(pcie->pci, PCI_CAP_ID_MSIX);
13101318
dw_pcie_remove_ext_capability(pcie->pci, PCI_EXT_CAP_ID_DPC);
13111319

1312-
qcom_ep_reset_deassert(pcie);
1320+
qcom_pcie_perst_deassert(pcie);
13131321

13141322
if (pcie->cfg->ops->config_sid) {
13151323
ret = pcie->cfg->ops->config_sid(pcie);
@@ -1320,7 +1328,7 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
13201328
return 0;
13211329

13221330
err_assert_reset:
1323-
qcom_ep_reset_assert(pcie);
1331+
qcom_pcie_perst_assert(pcie);
13241332
err_pwrctrl_power_off:
13251333
pci_pwrctrl_power_off_devices(pci->dev);
13261334
err_pwrctrl_destroy:
@@ -1339,7 +1347,7 @@ static void qcom_pcie_host_deinit(struct dw_pcie_rp *pp)
13391347
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
13401348
struct qcom_pcie *pcie = to_qcom_pcie(pci);
13411349

1342-
qcom_ep_reset_assert(pcie);
1350+
qcom_pcie_perst_assert(pcie);
13431351

13441352
/*
13451353
* No need to destroy pwrctrl devices as this function only gets called
@@ -1679,18 +1687,58 @@ static const struct pci_ecam_ops pci_qcom_ecam_ops = {
16791687
}
16801688
};
16811689

1682-
static int qcom_pcie_parse_port(struct qcom_pcie *pcie, struct device_node *node)
1690+
/* Parse PERST# from all nodes in depth first manner starting from @np */
1691+
static int qcom_pcie_parse_perst(struct qcom_pcie *pcie,
1692+
struct qcom_pcie_port *port,
1693+
struct device_node *np)
16831694
{
16841695
struct device *dev = pcie->pci->dev;
1685-
struct qcom_pcie_port *port;
1696+
struct qcom_pcie_perst *perst;
16861697
struct gpio_desc *reset;
1687-
struct phy *phy;
16881698
int ret;
16891699

1690-
reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(node),
1691-
"reset", GPIOD_OUT_HIGH, "PERST#");
1692-
if (IS_ERR(reset))
1700+
if (!of_find_property(np, "reset-gpios", NULL))
1701+
goto parse_child_node;
1702+
1703+
reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(np), "reset",
1704+
GPIOD_OUT_HIGH, "PERST#");
1705+
if (IS_ERR(reset)) {
1706+
/*
1707+
* FIXME: GPIOLIB currently supports exclusive GPIO access only.
1708+
* Non exclusive access is broken. But shared PERST# requires
1709+
* non-exclusive access. So once GPIOLIB properly supports it,
1710+
* implement it here.
1711+
*/
1712+
if (PTR_ERR(reset) == -EBUSY)
1713+
dev_err(dev, "Shared PERST# is not supported\n");
1714+
16931715
return PTR_ERR(reset);
1716+
}
1717+
1718+
perst = devm_kzalloc(dev, sizeof(*perst), GFP_KERNEL);
1719+
if (!perst)
1720+
return -ENOMEM;
1721+
1722+
INIT_LIST_HEAD(&perst->list);
1723+
perst->desc = reset;
1724+
list_add_tail(&perst->list, &port->perst);
1725+
1726+
parse_child_node:
1727+
for_each_available_child_of_node_scoped(np, child) {
1728+
ret = qcom_pcie_parse_perst(pcie, port, child);
1729+
if (ret)
1730+
return ret;
1731+
}
1732+
1733+
return 0;
1734+
}
1735+
1736+
static int qcom_pcie_parse_port(struct qcom_pcie *pcie, struct device_node *node)
1737+
{
1738+
struct device *dev = pcie->pci->dev;
1739+
struct qcom_pcie_port *port;
1740+
struct phy *phy;
1741+
int ret;
16941742

16951743
phy = devm_of_phy_get(dev, node, NULL);
16961744
if (IS_ERR(phy))
@@ -1704,7 +1752,12 @@ static int qcom_pcie_parse_port(struct qcom_pcie *pcie, struct device_node *node
17041752
if (ret)
17051753
return ret;
17061754

1707-
port->reset = reset;
1755+
INIT_LIST_HEAD(&port->perst);
1756+
1757+
ret = qcom_pcie_parse_perst(pcie, port, node);
1758+
if (ret)
1759+
return ret;
1760+
17081761
port->phy = phy;
17091762
INIT_LIST_HEAD(&port->list);
17101763
list_add_tail(&port->list, &pcie->ports);
@@ -1714,9 +1767,10 @@ static int qcom_pcie_parse_port(struct qcom_pcie *pcie, struct device_node *node
17141767

17151768
static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
17161769
{
1770+
struct qcom_pcie_perst *perst, *tmp_perst;
1771+
struct qcom_pcie_port *port, *tmp_port;
17171772
struct device *dev = pcie->pci->dev;
1718-
struct qcom_pcie_port *port, *tmp;
1719-
int ret = -ENOENT;
1773+
int ret = -ENODEV;
17201774

17211775
for_each_available_child_of_node_scoped(dev->of_node, of_port) {
17221776
if (!of_node_is_type(of_port, "pci"))
@@ -1729,7 +1783,9 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
17291783
return ret;
17301784

17311785
err_port_del:
1732-
list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
1786+
list_for_each_entry_safe(port, tmp_port, &pcie->ports, list) {
1787+
list_for_each_entry_safe(perst, tmp_perst, &port->perst, list)
1788+
list_del(&perst->list);
17331789
phy_exit(port->phy);
17341790
list_del(&port->list);
17351791
}
@@ -1740,6 +1796,7 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
17401796
static int qcom_pcie_parse_legacy_binding(struct qcom_pcie *pcie)
17411797
{
17421798
struct device *dev = pcie->pci->dev;
1799+
struct qcom_pcie_perst *perst;
17431800
struct qcom_pcie_port *port;
17441801
struct gpio_desc *reset;
17451802
struct phy *phy;
@@ -1761,19 +1818,28 @@ static int qcom_pcie_parse_legacy_binding(struct qcom_pcie *pcie)
17611818
if (!port)
17621819
return -ENOMEM;
17631820

1764-
port->reset = reset;
1821+
perst = devm_kzalloc(dev, sizeof(*perst), GFP_KERNEL);
1822+
if (!perst)
1823+
return -ENOMEM;
1824+
17651825
port->phy = phy;
17661826
INIT_LIST_HEAD(&port->list);
17671827
list_add_tail(&port->list, &pcie->ports);
17681828

1829+
perst->desc = reset;
1830+
INIT_LIST_HEAD(&port->perst);
1831+
INIT_LIST_HEAD(&perst->list);
1832+
list_add_tail(&perst->list, &port->perst);
1833+
17691834
return 0;
17701835
}
17711836

17721837
static int qcom_pcie_probe(struct platform_device *pdev)
17731838
{
1839+
struct qcom_pcie_perst *perst, *tmp_perst;
1840+
struct qcom_pcie_port *port, *tmp_port;
17741841
const struct qcom_pcie_cfg *pcie_cfg;
17751842
unsigned long max_freq = ULONG_MAX;
1776-
struct qcom_pcie_port *port, *tmp;
17771843
struct device *dev = &pdev->dev;
17781844
struct dev_pm_opp *opp;
17791845
struct qcom_pcie *pcie;
@@ -1913,7 +1979,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
19131979

19141980
ret = qcom_pcie_parse_ports(pcie);
19151981
if (ret) {
1916-
if (ret != -ENOENT) {
1982+
if (ret != -ENODEV) {
19171983
dev_err_probe(pci->dev, ret,
19181984
"Failed to parse Root Port: %d\n", ret);
19191985
goto err_pm_runtime_put;
@@ -1945,7 +2011,9 @@ static int qcom_pcie_probe(struct platform_device *pdev)
19452011
return 0;
19462012

19472013
err_phy_exit:
1948-
list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
2014+
list_for_each_entry_safe(port, tmp_port, &pcie->ports, list) {
2015+
list_for_each_entry_safe(perst, tmp_perst, &port->perst, list)
2016+
list_del(&perst->list);
19492017
phy_exit(port->phy);
19502018
list_del(&port->list);
19512019
}

0 commit comments

Comments
 (0)