PCI: mvebu: Obey bridge PCI_COMMAND_MEM and PCI_COMMAND_IO bits
[cascardo/linux.git] / drivers / pci / host / pci-mvebu.c
index 6f5a20f..9429412 100644 (file)
@@ -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;