Commit 7d761b08 authored by Sergio Paracuellos's avatar Sergio Paracuellos Committed by Greg Kroah-Hartman

staging: mt7621-pci: fix hang when nothing is connected to pcie ports

When nothing is connected to pcie ports, each port is set to reset state.
When this occurs, next access result in a hang on boot as follows:

mt7621-pci 1e140000.pcie: pcie0 no card, disable it (RST & CLK)
mt7621-pci 1e140000.pcie: pcie1 no card, disable it (RST & CLK)
mt7621-pci 1e140000.pcie: pcie2 no card, disable it (RST & CLK)
[ HANGS HERE ]

Fix this just detecting 'nothing is connected state' to avoid next accesses
to pcie port related configuration registers.

Fixes: b99cc3a2 ("staging: mt7621-pci: avoid custom 'map_irq' function")
Cc: stable <stable@vger.kernel.org>
Reported-by: default avatarDENG Qingfang <dqfext@gmail.com>
Signed-off-by: default avatarSergio Paracuellos <sergio.paracuellos@gmail.com>
Link: https://lore.kernel.org/r/20210823170803.2108-1-sergio.paracuellos@gmail.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a69bbd2f
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
#define PCIE_BAR_ENABLE BIT(0) #define PCIE_BAR_ENABLE BIT(0)
#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) #define PCIE_PORT_INT_EN(x) BIT(20 + (x))
#define PCIE_PORT_LINKUP BIT(0) #define PCIE_PORT_LINKUP BIT(0)
#define PCIE_PORT_CNT 3
#define PERST_DELAY_MS 100 #define PERST_DELAY_MS 100
...@@ -388,10 +389,11 @@ static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie) ...@@ -388,10 +389,11 @@ static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie)
msleep(PERST_DELAY_MS); msleep(PERST_DELAY_MS);
} }
static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) static int mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
{ {
struct device *dev = pcie->dev; struct device *dev = pcie->dev;
struct mt7621_pcie_port *port, *tmp; struct mt7621_pcie_port *port, *tmp;
u8 num_disabled = 0;
int err; int err;
mt7621_pcie_reset_assert(pcie); mt7621_pcie_reset_assert(pcie);
...@@ -423,6 +425,7 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) ...@@ -423,6 +425,7 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
slot); slot);
mt7621_control_assert(port); mt7621_control_assert(port);
port->enabled = false; port->enabled = false;
num_disabled++;
if (slot == 0) { if (slot == 0) {
tmp = port; tmp = port;
...@@ -433,6 +436,8 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie) ...@@ -433,6 +436,8 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
phy_power_off(tmp->phy); phy_power_off(tmp->phy);
} }
} }
return (num_disabled != PCIE_PORT_CNT) ? 0 : -ENODEV;
} }
static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port)
...@@ -540,7 +545,11 @@ static int mt7621_pci_probe(struct platform_device *pdev) ...@@ -540,7 +545,11 @@ static int mt7621_pci_probe(struct platform_device *pdev)
return err; return err;
} }
mt7621_pcie_init_ports(pcie); err = mt7621_pcie_init_ports(pcie);
if (err) {
dev_err(dev, "Nothing connected in virtual bridges\n");
return 0;
}
err = mt7621_pcie_enable_ports(bridge); err = mt7621_pcie_enable_ports(bridge);
if (err) { if (err) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment