summaryrefslogtreecommitdiff
path: root/drivers/pci/controller/pci-mvebu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/controller/pci-mvebu.c')
-rw-r--r--drivers/pci/controller/pci-mvebu.c29
1 files changed, 10 insertions, 19 deletions
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index a7eaa58483dd..806cfcdb6b44 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -438,12 +438,6 @@ static int mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
return mvebu_pcie_set_window(port, port->io_target, port->io_attr,
&desired, &port->iowin);
- if (!mvebu_has_ioport(port)) {
- dev_WARN(&port->pcie->pdev->dev,
- "Attempt to set IO when IO is disabled\n");
- return -EOPNOTSUPP;
- }
-
/*
* We read the PCI-to-PCI bridge emulated registers, and
* calculate the base address and size of the address decoding
@@ -599,24 +593,18 @@ mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
switch (reg) {
case PCI_COMMAND:
- if (!mvebu_has_ioport(port)) {
- conf->command = cpu_to_le16(
- le16_to_cpu(conf->command) & ~PCI_COMMAND_IO);
- new &= ~PCI_COMMAND_IO;
- }
-
mvebu_writel(port, new, PCIE_CMD_OFF);
break;
case PCI_IO_BASE:
- if ((mask & 0xffff) && mvebu_pcie_handle_iobase_change(port)) {
+ if ((mask & 0xffff) && mvebu_has_ioport(port) &&
+ mvebu_pcie_handle_iobase_change(port)) {
/* On error disable IO range */
conf->iobase &= ~0xf0;
conf->iolimit &= ~0xf0;
+ conf->iobase |= 0xf0;
conf->iobaseupper = cpu_to_le16(0x0000);
conf->iolimitupper = cpu_to_le16(0x0000);
- if (mvebu_has_ioport(port))
- conf->iobase |= 0xf0;
}
break;
@@ -630,14 +618,14 @@ mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
break;
case PCI_IO_BASE_UPPER16:
- if (mvebu_pcie_handle_iobase_change(port)) {
+ if (mvebu_has_ioport(port) &&
+ mvebu_pcie_handle_iobase_change(port)) {
/* On error disable IO range */
conf->iobase &= ~0xf0;
conf->iolimit &= ~0xf0;
+ conf->iobase |= 0xf0;
conf->iobaseupper = cpu_to_le16(0x0000);
conf->iolimitupper = cpu_to_le16(0x0000);
- if (mvebu_has_ioport(port))
- conf->iobase |= 0xf0;
}
break;
@@ -722,6 +710,7 @@ static const struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = {
*/
static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
{
+ unsigned int bridge_flags = PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD;
struct pci_bridge_emul *bridge = &port->bridge;
u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP);
u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS);
@@ -735,6 +724,8 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
/* We support 32 bits I/O addressing */
bridge->conf.iobase = PCI_IO_RANGE_TYPE_32;
bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32;
+ } else {
+ bridge_flags |= PCI_BRIDGE_EMUL_NO_IO_FORWARD;
}
/*
@@ -747,7 +738,7 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
bridge->data = port;
bridge->ops = &mvebu_pci_bridge_emul_ops;
- return pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD);
+ return pci_bridge_emul_init(bridge, bridge_flags);
}
static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys)