]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
pci: mvebu: fix the emulation of the status register
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>
Thu, 23 May 2013 14:32:53 +0000 (16:32 +0200)
committerJason Cooper <jason@lakedaemon.net>
Mon, 27 May 2013 16:01:15 +0000 (16:01 +0000)
The status register of the PCI configuration space of PCI-to-PCI
bridges contain some read-only bits, and so write-1-to-clear bits. So,
the Linux PCI core sometimes writes 0xffff to this status register,
and in the current PCI-to-PCI bridge emulation code of the Marvell
driver, we do take all those 1s being written. Even the read-only bits
are being overwritten.

For now, all the read-only bits should be emulated to have the zero
value.

The other bits, that are write-1-to-clear bits are used to report
various kind of errors, and are never set by the emulated bridge, so
there is no need to support this write-1-to-clear bits mechanism.

As a conclusion, the easiest solution is to simply emulate this status
register by returning zero when read, and ignore the writes to it.

This has two visible effects:

 * The devsel is no longer 'unknown' in, i.e

   Flags: bus master, 66MHz, user-definable features, ?? devsel, latency 0

   becomes:

   Flags: bus master, 66MHz, user-definable features, fast devsel, latency 0

   in lspci -v.

   This was caused by a value of 11b being read for devsel, which is
   an invalid value. This 11b value being read was due to a previous
   write of 0xffff into the status register.

 * The capability list is no longer broken, because we indicate to the
   Linux PCI core that we don't have a Capabilities Pointer in the PCI
   configuration space of this bridge. The following message is
   therefore no longer visible in lspci -v:

   Capabilities: [fc] <chain broken>

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
drivers/pci/host/pci-mvebu.c

index 9f1bfbd8116802c11482ef5353a95a50a1602d74..7d713024aba3a1892b43467ee4af2b235333fa32 100644 (file)
@@ -69,7 +69,6 @@ struct mvebu_sw_pci_bridge {
        u16 vendor;
        u16 device;
        u16 command;
-       u16 status;
        u16 class;
        u8 interface;
        u8 revision;
@@ -359,7 +358,6 @@ static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port)
 
        memset(bridge, 0, sizeof(struct mvebu_sw_pci_bridge));
 
-       bridge->status = PCI_STATUS_CAP_LIST;
        bridge->class = PCI_CLASS_BRIDGE_PCI;
        bridge->vendor = PCI_VENDOR_ID_MARVELL;
        bridge->device = MARVELL_EMULATED_PCI_PCI_BRIDGE_ID;
@@ -386,7 +384,7 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
                break;
 
        case PCI_COMMAND:
-               *value = bridge->status << 16 | bridge->command;
+               *value = bridge->command;
                break;
 
        case PCI_CLASS_REVISION:
@@ -479,7 +477,6 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port,
        switch (where & ~3) {
        case PCI_COMMAND:
                bridge->command = value & 0xffff;
-               bridge->status = value >> 16;
                break;
 
        case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1: