Skip to content

Commit d75404c

Browse files
paliLorenzo Pieralisi
authored andcommitted
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/[email protected] Fixes: 1f08673 ("PCI: mvebu: Convert to PCI emulated bridge config space") Signed-off-by: Pali Rohár <[email protected]> Signed-off-by: Lorenzo Pieralisi <[email protected]>
1 parent 91a8d79 commit d75404c

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

drivers/pci/controller/pci-mvebu.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#define PCIE_CTRL_OFF 0x1a00
5757
#define PCIE_CTRL_X1_MODE 0x0001
5858
#define PCIE_CTRL_RC_MODE BIT(1)
59+
#define PCIE_CTRL_MASTER_HOT_RESET BIT(24)
5960
#define PCIE_STAT_OFF 0x1a04
6061
#define PCIE_STAT_BUS 0xff00
6162
#define PCIE_STAT_DEV 0x1f0000
@@ -498,6 +499,22 @@ mvebu_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge,
498499
break;
499500
}
500501

502+
case PCI_INTERRUPT_LINE: {
503+
/*
504+
* From the whole 32bit register we support reading from HW only
505+
* one bit: PCI_BRIDGE_CTL_BUS_RESET.
506+
* Other bits are retrieved only from emulated config buffer.
507+
*/
508+
__le32 *cfgspace = (__le32 *)&bridge->conf;
509+
u32 val = le32_to_cpu(cfgspace[PCI_INTERRUPT_LINE / 4]);
510+
if (mvebu_readl(port, PCIE_CTRL_OFF) & PCIE_CTRL_MASTER_HOT_RESET)
511+
val |= PCI_BRIDGE_CTL_BUS_RESET << 16;
512+
else
513+
val &= ~(PCI_BRIDGE_CTL_BUS_RESET << 16);
514+
*value = val;
515+
break;
516+
}
517+
501518
default:
502519
return PCI_BRIDGE_EMUL_NOT_HANDLED;
503520
}
@@ -606,6 +623,17 @@ mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
606623
mvebu_pcie_set_local_bus_nr(port, conf->secondary_bus);
607624
break;
608625

626+
case PCI_INTERRUPT_LINE:
627+
if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) {
628+
u32 ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
629+
if (new & (PCI_BRIDGE_CTL_BUS_RESET << 16))
630+
ctrl |= PCIE_CTRL_MASTER_HOT_RESET;
631+
else
632+
ctrl &= ~PCIE_CTRL_MASTER_HOT_RESET;
633+
mvebu_writel(port, ctrl, PCIE_CTRL_OFF);
634+
}
635+
break;
636+
609637
default:
610638
break;
611639
}

0 commit comments

Comments
 (0)