/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) */ #include #include #include #include static int mv_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) { struct mv_pci_controller *mvbc = bus->sysdata; unsigned long address_reg, data_reg; u32 address; address_reg = mvbc->config_addr; data_reg = mvbc->config_vreg; /* Accessing device 31 crashes those Marvells. Since years. Will they ever make sane controllers ... */ if (PCI_SLOT(devfn) == 31) return PCIBIOS_DEVICE_NOT_FOUND; address = (bus->number << 16) | (devfn << 8) | (where & 0xfc) | 0x80000000; /* start the configuration cycle */ MV_WRITE(address_reg, address); switch (size) { case 1: *val = MV_READ_8(data_reg + (where & 0x3)); break; case 2: *val = MV_READ_16(data_reg + (where & 0x3)); break; case 4: *val = MV_READ(data_reg); break; } return PCIBIOS_SUCCESSFUL; } static int mv_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { struct mv_pci_controller *mvbc = bus->sysdata; unsigned long address_reg, data_reg; u32 address; address_reg = mvbc->config_addr; data_reg = mvbc->config_vreg; /* Accessing device 31 crashes those Marvells. Since years. Will they ever make sane controllers ... */ if (PCI_SLOT(devfn) == 31) return PCIBIOS_DEVICE_NOT_FOUND; address = (bus->number << 16) | (devfn << 8) | (where & 0xfc) | 0x80000000; /* start the configuration cycle */ MV_WRITE(address_reg, address); switch (size) { case 1: MV_WRITE_8(data_reg + (where & 0x3), val); break; case 2: MV_WRITE_16(data_reg + (where & 0x3), val); break; case 4: MV_WRITE(data_reg, val); break; } return PCIBIOS_SUCCESSFUL; } struct pci_ops mv_pci_ops = { .read = mv_read_config, .write = mv_write_config };