diff options
Diffstat (limited to 'arch/mips/pci/ops-bcm63xx.c')
-rw-r--r-- | arch/mips/pci/ops-bcm63xx.c | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c index 822ae179bc56..65c7bd100486 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 = { | |||
411 | * only one IO window, so it cannot be shared by PCI and cardbus, use | 411 | * only one IO window, so it cannot be shared by PCI and cardbus, use |
412 | * fixup to choose and detect unhandled configuration | 412 | * fixup to choose and detect unhandled configuration |
413 | */ | 413 | */ |
414 | static void bcm63xx_fixup(struct pci_dev *dev) | 414 | static void __devinit bcm63xx_fixup(struct pci_dev *dev) |
415 | { | 415 | { |
416 | static int io_window = -1; | 416 | static int io_window = -1; |
417 | int i, found, new_io_window; | 417 | int i, found, new_io_window; |
@@ -465,3 +465,64 @@ static void bcm63xx_fixup(struct pci_dev *dev) | |||
465 | 465 | ||
466 | DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup); | 466 | DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup); |
467 | #endif | 467 | #endif |
468 | |||
469 | static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn) | ||
470 | { | ||
471 | switch (bus->number) { | ||
472 | case PCIE_BUS_BRIDGE: | ||
473 | return (PCI_SLOT(devfn) == 0); | ||
474 | case PCIE_BUS_DEVICE: | ||
475 | if (PCI_SLOT(devfn) == 0) | ||
476 | return bcm_pcie_readl(PCIE_DLSTATUS_REG) | ||
477 | & DLSTATUS_PHYLINKUP; | ||
478 | default: | ||
479 | return false; | ||
480 | } | ||
481 | } | ||
482 | |||
483 | static int bcm63xx_pcie_read(struct pci_bus *bus, unsigned int devfn, | ||
484 | int where, int size, u32 *val) | ||
485 | { | ||
486 | u32 data; | ||
487 | u32 reg = where & ~3; | ||
488 | |||
489 | if (!bcm63xx_pcie_can_access(bus, devfn)) | ||
490 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
491 | |||
492 | if (bus->number == PCIE_BUS_DEVICE) | ||
493 | reg += PCIE_DEVICE_OFFSET; | ||
494 | |||
495 | data = bcm_pcie_readl(reg); | ||
496 | |||
497 | *val = postprocess_read(data, where, size); | ||
498 | |||
499 | return PCIBIOS_SUCCESSFUL; | ||
500 | |||
501 | } | ||
502 | |||
503 | static int bcm63xx_pcie_write(struct pci_bus *bus, unsigned int devfn, | ||
504 | int where, int size, u32 val) | ||
505 | { | ||
506 | u32 data; | ||
507 | u32 reg = where & ~3; | ||
508 | |||
509 | if (!bcm63xx_pcie_can_access(bus, devfn)) | ||
510 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
511 | |||
512 | if (bus->number == PCIE_BUS_DEVICE) | ||
513 | reg += PCIE_DEVICE_OFFSET; | ||
514 | |||
515 | |||
516 | data = bcm_pcie_readl(reg); | ||
517 | |||
518 | data = preprocess_write(data, val, where, size); | ||
519 | bcm_pcie_writel(data, reg); | ||
520 | |||
521 | return PCIBIOS_SUCCESSFUL; | ||
522 | } | ||
523 | |||
524 | |||
525 | struct pci_ops bcm63xx_pcie_ops = { | ||
526 | .read = bcm63xx_pcie_read, | ||
527 | .write = bcm63xx_pcie_write | ||
528 | }; | ||