Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43a16f94 authored by Jason Gunthorpe's avatar Jason Gunthorpe Committed by Bjorn Helgaas
Browse files

PCI: mvebu: Obey bridge PCI_COMMAND_MEM and PCI_COMMAND_IO bits



When PCI_COMMAND_MEMORY/PCI_COMMAND_IO are cleared, the bridge should not
allocate windows or even look at the window limit/base registers.

Otherwise we may set up bogus windows while the PCI core code performs
discovery.  The core will leave PCI_COMMAND_IO cleared if it doesn't need
an IO window.

Have mvebu_pcie_handle_*_change respect the bits, and call the change
function whenever the bits changes.

Tested-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: default avatarJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarJason Cooper <jason@lakedaemon.net>
parent 2850b05c
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -300,7 +300,8 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)

	/* Are the new iobase/iolimit values invalid? */
	if (port->bridge.iolimit < port->bridge.iobase ||
	    port->bridge.iolimitupper < port->bridge.iobaseupper) {
	    port->bridge.iolimitupper < port->bridge.iobaseupper ||
	    !(port->bridge.command & PCI_COMMAND_IO)) {

		/* If a window was configured, remove it */
		if (port->iowin_base) {
@@ -337,7 +338,8 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
{
	/* Are the new membase/memlimit values invalid? */
	if (port->bridge.memlimit < port->bridge.membase) {
	if (port->bridge.memlimit < port->bridge.membase ||
	    !(port->bridge.command & PCI_COMMAND_MEMORY)) {

		/* If a window was configured, remove it */
		if (port->memwin_base) {
@@ -485,8 +487,16 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port,

	switch (where & ~3) {
	case PCI_COMMAND:
	{
		u32 old = bridge->command;

		bridge->command = value & 0xffff;
		if ((old ^ bridge->command) & PCI_COMMAND_IO)
			mvebu_pcie_handle_iobase_change(port);
		if ((old ^ bridge->command) & PCI_COMMAND_MEMORY)
			mvebu_pcie_handle_membase_change(port);
		break;
	}

	case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1:
		bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4] = value;