mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 16:54:20 +08:00
PCI: mvebu: Fix support for PCI_BRIDGE_CTL_BUS_RESET on emulated bridge
Hardware supports PCIe Hot Reset via PCIE_CTRL_OFF register. Use it for
implementing PCI_BRIDGE_CTL_BUS_RESET bit of PCI_BRIDGE_CONTROL register on
emulated bridge.
With this change the function pci_reset_secondary_bus() starts working and
can reset connected PCIe card.
Link: https://lore.kernel.org/r/20211125124605.25915-13-pali@kernel.org
Fixes: 1f08673eef
("PCI: mvebu: Convert to PCI emulated bridge config space")
Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
This commit is contained in:
parent
91a8d79fc7
commit
d75404cc08
@ -56,6 +56,7 @@
|
||||
#define PCIE_CTRL_OFF 0x1a00
|
||||
#define PCIE_CTRL_X1_MODE 0x0001
|
||||
#define PCIE_CTRL_RC_MODE BIT(1)
|
||||
#define PCIE_CTRL_MASTER_HOT_RESET BIT(24)
|
||||
#define PCIE_STAT_OFF 0x1a04
|
||||
#define PCIE_STAT_BUS 0xff00
|
||||
#define PCIE_STAT_DEV 0x1f0000
|
||||
@ -498,6 +499,22 @@ mvebu_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge,
|
||||
break;
|
||||
}
|
||||
|
||||
case PCI_INTERRUPT_LINE: {
|
||||
/*
|
||||
* From the whole 32bit register we support reading from HW only
|
||||
* one bit: PCI_BRIDGE_CTL_BUS_RESET.
|
||||
* Other bits are retrieved only from emulated config buffer.
|
||||
*/
|
||||
__le32 *cfgspace = (__le32 *)&bridge->conf;
|
||||
u32 val = le32_to_cpu(cfgspace[PCI_INTERRUPT_LINE / 4]);
|
||||
if (mvebu_readl(port, PCIE_CTRL_OFF) & PCIE_CTRL_MASTER_HOT_RESET)
|
||||
val |= PCI_BRIDGE_CTL_BUS_RESET << 16;
|
||||
else
|
||||
val &= ~(PCI_BRIDGE_CTL_BUS_RESET << 16);
|
||||
*value = val;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return PCI_BRIDGE_EMUL_NOT_HANDLED;
|
||||
}
|
||||
@ -606,6 +623,17 @@ mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
|
||||
mvebu_pcie_set_local_bus_nr(port, conf->secondary_bus);
|
||||
break;
|
||||
|
||||
case PCI_INTERRUPT_LINE:
|
||||
if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) {
|
||||
u32 ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
|
||||
if (new & (PCI_BRIDGE_CTL_BUS_RESET << 16))
|
||||
ctrl |= PCIE_CTRL_MASTER_HOT_RESET;
|
||||
else
|
||||
ctrl &= ~PCIE_CTRL_MASTER_HOT_RESET;
|
||||
mvebu_writel(port, ctrl, PCIE_CTRL_OFF);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user