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: b99cc3a2b6
("staging: mt7621-pci: avoid custom 'map_irq' function")
Cc: stable <stable@vger.kernel.org>
Reported-by: DENG Qingfang <dqfext@gmail.com>
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
Link: https://lore.kernel.org/r/20210823170803.2108-1-sergio.paracuellos@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
a69bbd2f77
commit
7d761b084b
|
@ -56,6 +56,7 @@
|
|||
#define PCIE_BAR_ENABLE BIT(0)
|
||||
#define PCIE_PORT_INT_EN(x) BIT(20 + (x))
|
||||
#define PCIE_PORT_LINKUP BIT(0)
|
||||
#define PCIE_PORT_CNT 3
|
||||
|
||||
#define PERST_DELAY_MS 100
|
||||
|
||||
|
@ -388,10 +389,11 @@ static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie)
|
|||
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 mt7621_pcie_port *port, *tmp;
|
||||
u8 num_disabled = 0;
|
||||
int err;
|
||||
|
||||
mt7621_pcie_reset_assert(pcie);
|
||||
|
@ -423,6 +425,7 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
|
|||
slot);
|
||||
mt7621_control_assert(port);
|
||||
port->enabled = false;
|
||||
num_disabled++;
|
||||
|
||||
if (slot == 0) {
|
||||
tmp = port;
|
||||
|
@ -433,6 +436,8 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
|
|||
phy_power_off(tmp->phy);
|
||||
}
|
||||
}
|
||||
|
||||
return (num_disabled != PCIE_PORT_CNT) ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port)
|
||||
|
@ -540,7 +545,11 @@ static int mt7621_pci_probe(struct platform_device *pdev)
|
|||
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);
|
||||
if (err) {
|
||||
|
|
Loading…
Reference in New Issue