static int mvebu_pcie_write_config_dword(struct pci_controller *hose, pci_dev_t dev, int offset, u32 val) { struct mvebu_pcie *pcie = hose_to_pcie(hose); int local_bus = PCI_BUS(pcie->dev); int local_dev = PCI_DEV(pcie->dev); /* Only allow one other device besides the local one on the local bus */ if (PCI_BUS(dev) == local_bus && PCI_DEV(dev) != local_dev) { if (local_dev == 0 && PCI_DEV(dev) != 1) { /* * If local dev is 0, the first other dev can * only be 1 */ return 1; } else if (local_dev != 0 && PCI_DEV(dev) != 0) { /* * If local dev is not 0, the first other dev can * only be 0 */ return 1; } } writel(PCIE_CONF_ADDR(dev, offset), pcie->base + PCIE_CONF_ADDR_OFF); writel(val, pcie->base + PCIE_CONF_DATA_OFF); return 0; }
static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port, struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where), PCIE_CONF_ADDR_OFF); *val = mvebu_readl(port, PCIE_CONF_DATA_OFF); if (size == 1) *val = (*val >> (8 * (where & 3))) & 0xff; else if (size == 2)
static int mvebu_pcie_indirect_rd_conf(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { struct mvebu_pcie *pcie = to_pcie(bus->host); /* Skip all requests not directed to device behind bridge */ if (devfn != pcie->devfn || !mvebu_pcie_link_up(pcie)) { *val = 0xffffffff; return PCIBIOS_DEVICE_NOT_FOUND; } writel(PCIE_CONF_ADDR(bus->number, devfn, where), pcie->base + PCIE_CONF_ADDR_OFF); *val = readl(pcie->base + PCIE_CONF_DATA_OFF); if (size == 1) *val = (*val >> (8 * (where & 3))) & 0xff; else if (size == 2)