1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) 7 */ 8#include <linux/kernel.h> 9#include <linux/types.h> 10#include <linux/pci.h> 11 12#include <asm/marvell.h> 13 14static int mv_read_config(struct pci_bus *bus, unsigned int devfn, 15 int where, int size, u32 * val) 16{ 17 struct mv_pci_controller *mvbc = bus->sysdata; 18 unsigned long address_reg, data_reg; 19 u32 address; 20 21 address_reg = mvbc->config_addr; 22 data_reg = mvbc->config_vreg; 23 24 /* Accessing device 31 crashes those Marvells. Since years. 25 Will they ever make sane controllers ... */ 26 if (PCI_SLOT(devfn) == 31) 27 return PCIBIOS_DEVICE_NOT_FOUND; 28 29 address = (bus->number << 16) | (devfn << 8) | 30 (where & 0xfc) | 0x80000000; 31 32 /* start the configuration cycle */ 33 MV_WRITE(address_reg, address); 34 35 switch (size) { 36 case 1: 37 *val = MV_READ_8(data_reg + (where & 0x3)); 38 break; 39 40 case 2: 41 *val = MV_READ_16(data_reg + (where & 0x3)); 42 break; 43 44 case 4: 45 *val = MV_READ(data_reg); 46 break; 47 } 48 49 return PCIBIOS_SUCCESSFUL; 50} 51 52static int mv_write_config(struct pci_bus *bus, unsigned int devfn, 53 int where, int size, u32 val) 54{ 55 struct mv_pci_controller *mvbc = bus->sysdata; 56 unsigned long address_reg, data_reg; 57 u32 address; 58 59 address_reg = mvbc->config_addr; 60 data_reg = mvbc->config_vreg; 61 62 /* Accessing device 31 crashes those Marvells. Since years. 63 Will they ever make sane controllers ... */ 64 if (PCI_SLOT(devfn) == 31) 65 return PCIBIOS_DEVICE_NOT_FOUND; 66 67 address = (bus->number << 16) | (devfn << 8) | 68 (where & 0xfc) | 0x80000000; 69 70 /* start the configuration cycle */ 71 MV_WRITE(address_reg, address); 72 73 switch (size) { 74 case 1: 75 MV_WRITE_8(data_reg + (where & 0x3), val); 76 break; 77 78 case 2: 79 MV_WRITE_16(data_reg + (where & 0x3), val); 80 break; 81 82 case 4: 83 MV_WRITE(data_reg, val); 84 break; 85 } 86 87 return PCIBIOS_SUCCESSFUL; 88} 89 90struct pci_ops mv_pci_ops = { 91 .read = mv_read_config, 92 .write = mv_write_config 93}; 94