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

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.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a69bbd2f
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -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) {