summaryrefslogtreecommitdiffstats
path: root/arch/mips/pci/ops-bcm63xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/pci/ops-bcm63xx.c')
-rw-r--r--arch/mips/pci/ops-bcm63xx.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c
index 822ae179bc5..65c7bd10048 100644
--- a/arch/mips/pci/ops-bcm63xx.c
+++ b/arch/mips/pci/ops-bcm63xx.c
@@ -411,7 +411,7 @@ struct pci_ops bcm63xx_cb_ops = {
* only one IO window, so it cannot be shared by PCI and cardbus, use
* fixup to choose and detect unhandled configuration
*/
-static void bcm63xx_fixup(struct pci_dev *dev)
+static void __devinit bcm63xx_fixup(struct pci_dev *dev)
{
static int io_window = -1;
int i, found, new_io_window;
@@ -465,3 +465,64 @@ static void bcm63xx_fixup(struct pci_dev *dev)
DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup);
#endif
+
+static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn)
+{
+ switch (bus->number) {
+ case PCIE_BUS_BRIDGE:
+ return (PCI_SLOT(devfn) == 0);
+ case PCIE_BUS_DEVICE:
+ if (PCI_SLOT(devfn) == 0)
+ return bcm_pcie_readl(PCIE_DLSTATUS_REG)
+ & DLSTATUS_PHYLINKUP;
+ default:
+ return false;
+ }
+}
+
+static int bcm63xx_pcie_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ u32 data;
+ u32 reg = where & ~3;
+
+ if (!bcm63xx_pcie_can_access(bus, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (bus->number == PCIE_BUS_DEVICE)
+ reg += PCIE_DEVICE_OFFSET;
+
+ data = bcm_pcie_readl(reg);
+
+ *val = postprocess_read(data, where, size);
+
+ return PCIBIOS_SUCCESSFUL;
+
+}
+
+static int bcm63xx_pcie_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data;
+ u32 reg = where & ~3;
+
+ if (!bcm63xx_pcie_can_access(bus, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (bus->number == PCIE_BUS_DEVICE)
+ reg += PCIE_DEVICE_OFFSET;
+
+
+ data = bcm_pcie_readl(reg);
+
+ data = preprocess_write(data, val, where, size);
+ bcm_pcie_writel(data, reg);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+struct pci_ops bcm63xx_pcie_ops = {
+ .read = bcm63xx_pcie_read,
+ .write = bcm63xx_pcie_write
+};