aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gunthorpe <jgunthorpe@obsidianresearch.com>2013-10-01 13:58:00 -0400
committerJason Cooper <jason@lakedaemon.net>2013-10-08 12:45:16 -0400
commit9f352f0e6c0fa2dc608812df297769789b7ecc51 (patch)
tree3b31078c8202355ee95240008cd4769042bee766
parent96ae0b548672adc12431312718835e77472f5bf0 (diff)
PCI: mvebu: Dynamically detect if the PEX link is up to enable hot plug
Otherwise hotplugging the PEX doesn't work at all since the driver detects the link state at probe time. Simply replacing the two tests of haslink with a register read is enough to fix it. Tested on kirkwood with repeated plug/unplug of the link partner. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Acked-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--drivers/pci/host/pci-mvebu.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 77f8a7c58597..10c0895e42b3 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -120,7 +120,6 @@ struct mvebu_pcie_port {
120 char *name; 120 char *name;
121 void __iomem *base; 121 void __iomem *base;
122 spinlock_t conf_lock; 122 spinlock_t conf_lock;
123 int haslink;
124 u32 port; 123 u32 port;
125 u32 lane; 124 u32 lane;
126 int devfn; 125 int devfn;
@@ -560,7 +559,7 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
560 if (bus->number == 0) 559 if (bus->number == 0)
561 return mvebu_sw_pci_bridge_write(port, where, size, val); 560 return mvebu_sw_pci_bridge_write(port, where, size, val);
562 561
563 if (!port->haslink) 562 if (!mvebu_pcie_link_up(port))
564 return PCIBIOS_DEVICE_NOT_FOUND; 563 return PCIBIOS_DEVICE_NOT_FOUND;
565 564
566 /* 565 /*
@@ -602,7 +601,7 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
602 if (bus->number == 0) 601 if (bus->number == 0)
603 return mvebu_sw_pci_bridge_read(port, where, size, val); 602 return mvebu_sw_pci_bridge_read(port, where, size, val);
604 603
605 if (!port->haslink) { 604 if (!mvebu_pcie_link_up(port)) {
606 *val = 0xffffffff; 605 *val = 0xffffffff;
607 return PCIBIOS_DEVICE_NOT_FOUND; 606 return PCIBIOS_DEVICE_NOT_FOUND;
608 } 607 }
@@ -950,14 +949,12 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
950 949
951 mvebu_pcie_set_local_dev_nr(port, 1); 950 mvebu_pcie_set_local_dev_nr(port, 1);
952 951
953 if (mvebu_pcie_link_up(port)) { 952 port->clk = of_clk_get_by_name(child, NULL);
954 port->haslink = 1; 953 if (IS_ERR(port->clk)) {
955 dev_info(&pdev->dev, "PCIe%d.%d: link up\n", 954 dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
956 port->port, port->lane); 955 port->port, port->lane);
957 } else { 956 iounmap(port->base);
958 port->haslink = 0; 957 continue;
959 dev_info(&pdev->dev, "PCIe%d.%d: link down\n",
960 port->port, port->lane);
961 } 958 }
962 959
963 port->dn = child; 960 port->dn = child;