|
@@ -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;
|