Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.10 146 lines 3.6 kB view raw
1#include <linux/kernel.h> 2#include <linux/init.h> 3#include <linux/pci.h> 4#include <asm/bootinfo.h> 5 6#include <asm/lasat/lasat.h> 7#include <asm/nile4.h> 8 9#define PCI_ACCESS_READ 0 10#define PCI_ACCESS_WRITE 1 11 12#define LO(reg) (reg / 4) 13#define HI(reg) (reg / 4 + 1) 14 15volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; 16 17static DEFINE_SPINLOCK(nile4_pci_lock); 18 19static int nile4_pcibios_config_access(unsigned char access_type, 20 struct pci_bus *bus, unsigned int devfn, int where, u32 *val) 21{ 22 unsigned char busnum = bus->number; 23 u32 adr, mask, err; 24 25 if ((busnum == 0) && (PCI_SLOT(devfn) > 8)) 26 /* The addressing scheme chosen leaves room for just 27 * 8 devices on the first busnum (besides the PCI 28 * controller itself) */ 29 return PCIBIOS_DEVICE_NOT_FOUND; 30 31 if ((busnum == 0) && (devfn == PCI_DEVFN(0, 0))) { 32 /* Access controller registers directly */ 33 if (access_type == PCI_ACCESS_WRITE) { 34 vrc_pciregs[(0x200 + where) >> 2] = *val; 35 } else { 36 *val = vrc_pciregs[(0x200 + where) >> 2]; 37 } 38 return PCIBIOS_SUCCESSFUL; 39 } 40 41 /* Temporarily map PCI Window 1 to config space */ 42 mask = vrc_pciregs[LO(NILE4_PCIINIT1)]; 43 vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (busnum ? 0x200 : 0); 44 45 /* Clear PCI Error register. This also clears the Error Type 46 * bits in the Control register */ 47 vrc_pciregs[LO(NILE4_PCIERR)] = 0; 48 vrc_pciregs[HI(NILE4_PCIERR)] = 0; 49 50 /* Setup address */ 51 if (busnum == 0) 52 adr = 53 KSEG1ADDR(PCI_WINDOW1) + 54 ((1 << (PCI_SLOT(devfn) + 15)) | (PCI_FUNC(devfn) << 8) 55 | (where & ~3)); 56 else 57 adr = KSEG1ADDR(PCI_WINDOW1) | (busnum << 16) | (devfn << 8) | 58 (where & ~3); 59 60 if (access_type == PCI_ACCESS_WRITE) 61 *(u32 *) adr = *val; 62 else 63 *val = *(u32 *) adr; 64 65 /* Check for master or target abort */ 66 err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7; 67 68 /* Restore PCI Window 1 */ 69 vrc_pciregs[LO(NILE4_PCIINIT1)] = mask; 70 71 if (err) 72 return PCIBIOS_DEVICE_NOT_FOUND; 73 74 return PCIBIOS_SUCCESSFUL; 75} 76 77static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, 78 int where, int size, u32 *val) 79{ 80 unsigned long flags; 81 u32 data = 0; 82 int err; 83 84 if ((size == 2) && (where & 1)) 85 return PCIBIOS_BAD_REGISTER_NUMBER; 86 else if ((size == 4) && (where & 3)) 87 return PCIBIOS_BAD_REGISTER_NUMBER; 88 89 spin_lock_irqsave(&nile4_pci_lock, flags); 90 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, 91 &data); 92 spin_unlock_irqrestore(&nile4_pci_lock, flags); 93 94 if (err) 95 return err; 96 97 if (size == 1) 98 *val = (data >> ((where & 3) << 3)) & 0xff; 99 else if (size == 2) 100 *val = (data >> ((where & 3) << 3)) & 0xffff; 101 else 102 *val = data; 103 104 return PCIBIOS_SUCCESSFUL; 105} 106 107static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, 108 int where, int size, u32 val) 109{ 110 unsigned long flags; 111 u32 data = 0; 112 int err; 113 114 if ((size == 2) && (where & 1)) 115 return PCIBIOS_BAD_REGISTER_NUMBER; 116 else if ((size == 4) && (where & 3)) 117 return PCIBIOS_BAD_REGISTER_NUMBER; 118 119 spin_lock_irqsave(&nile4_pci_lock, flags); 120 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, 121 &data); 122 spin_unlock_irqrestore(&nile4_pci_lock, flags); 123 124 if (err) 125 return err; 126 127 if (size == 1) 128 data = (data & ~(0xff << ((where & 3) << 3))) | 129 (val << ((where & 3) << 3)); 130 else if (size == 2) 131 data = (data & ~(0xffff << ((where & 3) << 3))) | 132 (val << ((where & 3) << 3)); 133 else 134 data = val; 135 136 if (nile4_pcibios_config_access 137 (PCI_ACCESS_WRITE, bus, devfn, where, &data)) 138 return -1; 139 140 return PCIBIOS_SUCCESSFUL; 141} 142 143struct pci_ops nile4_pci_ops = { 144 .read = nile4_pcibios_read, 145 .write = nile4_pcibios_write, 146};