Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
[linux-2.6] / arch / mips / pci / ops-mace.c
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) 2000, 2001 Keith M Wesolowski
7  */
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/pci.h>
11 #include <linux/types.h>
12 #include <asm/pci.h>
13 #include <asm/ip32/mace.h>
14
15 #if 0
16 # define DPRINTK(args...) printk(args);
17 #else
18 # define DPRINTK(args...)
19 #endif
20
21 /*
22  * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
23  * map looks like this:
24  *
25  * 0  aic7xxx 0
26  * 1  aic7xxx 1
27  * 2  expansion slot
28  * 3  N/C
29  * 4  N/C
30  */
31
32 #define chkslot(_bus,_devfn)                                    \
33 do {                                                            \
34         if ((_bus)->number > 0 || PCI_SLOT (_devfn) < 1 \
35             || PCI_SLOT (_devfn) > 3)                           \
36                 return PCIBIOS_DEVICE_NOT_FOUND;                \
37 } while (0)
38
39 #define mkaddr(_devfn, _reg) \
40 ((((_devfn) & 0xffUL) << 8) | ((_reg) & 0xfcUL))
41
42 static int
43 mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
44                      int reg, int size, u32 *val)
45 {
46         chkslot(bus, devfn);
47         mace->pci.config_addr = mkaddr(devfn, reg);
48         switch (size) {
49         case 1:
50                 *val = mace->pci.config_data.b[(reg & 3) ^ 3];
51                 break;
52         case 2:
53                 *val = mace->pci.config_data.w[((reg >> 1) & 1) ^ 1];
54                 break;
55         case 4:
56                 *val = mace->pci.config_data.l;
57                 break;
58         }
59
60         DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val);
61
62         return PCIBIOS_SUCCESSFUL;
63 }
64
65 static int
66 mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
67                       int reg, int size, u32 val)
68 {
69         chkslot(bus, devfn);
70         mace->pci.config_addr = mkaddr(devfn, reg);
71         switch (size) {
72         case 1:
73                 mace->pci.config_data.b[(reg & 3) ^ 3] = val;
74                 break;
75         case 2:
76                 mace->pci.config_data.w[((reg >> 1) & 1) ^ 1] = val;
77                 break;
78         case 4:
79                 mace->pci.config_data.l = val;
80                 break;
81         }
82
83         DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val);
84
85         return PCIBIOS_SUCCESSFUL;
86 }
87
88 struct pci_ops mace_pci_ops = {
89         .read = mace_pci_read_config,
90         .write = mace_pci_write_config,
91 };