convert aruba to the new structure
[15.05/openwrt.git] / target / linux / aruba-2.6 / files / arch / mips / pci / ops-aruba.c
1 /**************************************************************************
2  *
3  *  BRIEF MODULE DESCRIPTION
4  *     pci_ops for IDT EB434 board
5  *
6  *  Copyright 2004 IDT Inc. (rischelp@idt.com)
7  *         
8  *  This program is free software; you can redistribute  it and/or modify it
9  *  under  the terms of  the GNU General  Public License as published by the
10  *  Free Software Foundation;  either version 2 of the  License, or (at your
11  *  option) any later version.
12  *
13  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
14  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
15  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
16  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
17  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
19  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
21  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  *  You should have received a copy of the  GNU General Public License along
25  *  with this program; if not, write  to the Free Software Foundation, Inc.,
26  *  675 Mass Ave, Cambridge, MA 02139, USA.
27  *
28  *
29  **************************************************************************
30  * May 2004 rkt, neb
31  *
32  * Initial Release
33  *
34  * 
35  *
36  **************************************************************************
37  */
38
39 #include <linux/autoconf.h>
40 #include <linux/init.h>
41 #include <linux/pci.h>
42 #include <linux/types.h>
43 #include <linux/delay.h>
44
45 #include <asm/cpu.h>
46 #include <asm/io.h>
47
48 #include <asm/idt-boards/rc32434/rc32434.h>
49 #include <asm/idt-boards/rc32434/rc32434_pci.h>
50
51 #define PCI_ACCESS_READ  0
52 #define PCI_ACCESS_WRITE 1
53
54
55 #define PCI_CFG_SET(slot,func,off) \
56         (rc32434_pci->pcicfga = (0x80000000 | ((slot)<<11) | \
57                             ((func)<<8) | (off)))
58
59 static int config_access(unsigned char access_type, struct pci_bus *bus,
60                          unsigned int devfn, unsigned char where,
61                          u32 * data)
62
63         /*
64          * config cycles are on 4 byte boundary only
65          */
66         unsigned int slot = PCI_SLOT(devfn);
67         u8 func = PCI_FUNC(devfn);
68         
69         if (slot < 2 || slot > 15) {
70                 *data = 0xFFFFFFFF;
71                 return -1;
72         }
73         /* Setup address */
74         PCI_CFG_SET(slot, func, where);
75         rc32434_sync();
76         
77         if (access_type == PCI_ACCESS_WRITE) {
78                 rc32434_sync(); 
79                 rc32434_pci->pcicfgd = *data;
80         } else {
81                 rc32434_sync(); 
82                 *data = rc32434_pci->pcicfgd;
83         }
84         
85         rc32434_sync();
86         
87         return 0;
88 }
89
90
91 /*
92  * We can't address 8 and 16 bit words directly.  Instead we have to
93  * read/write a 32bit word and mask/modify the data we actually want.
94  */
95 static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
96                             int where, u8 * val)
97 {
98         u32 data;
99         int ret;
100         
101         ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
102         *val = (data >> ((where & 3) << 3)) & 0xff;
103         return ret;
104 }
105
106 static int read_config_word(struct pci_bus *bus, unsigned int devfn,
107                             int where, u16 * val)
108 {
109         u32 data;
110         int ret;
111         
112         ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
113         *val = (data >> ((where & 3) << 3)) & 0xffff;
114         return ret;
115 }
116
117 static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
118                              int where, u32 * val)
119 {
120         int ret;
121         
122         ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
123         return ret;
124 }
125
126 static int
127 write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
128                   u8 val)
129 {
130         u32 data = 0;
131         
132         if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
133                 return -1;
134         
135         data = (data & ~(0xff << ((where & 3) << 3))) |
136                 (val << ((where & 3) << 3));
137         
138         if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
139                 return -1;
140         
141         return PCIBIOS_SUCCESSFUL;
142 }
143
144
145 static int
146 write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
147                   u16 val)
148 {
149         u32 data = 0;
150         
151         if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
152                 return -1;
153         
154         data = (data & ~(0xffff << ((where & 3) << 3))) |
155                 (val << ((where & 3) << 3));
156         
157         if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
158                 return -1;
159         
160         
161         return PCIBIOS_SUCCESSFUL;
162 }
163
164
165 static int 
166 write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
167                    u32 val)
168 {
169         if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
170                 return -1;
171         
172         return PCIBIOS_SUCCESSFUL;
173 }
174
175 static int pci_config_read(struct pci_bus *bus, unsigned int devfn,
176                            int where, int size, u32 * val)
177 {
178         switch (size) {
179         case 1: 
180                 return read_config_byte(bus, devfn, where, (u8 *) val);
181         case 2: 
182                 return read_config_word(bus, devfn, where, (u16 *) val);
183         default:
184                 return read_config_dword(bus, devfn, where, val);
185         }
186 }
187
188 static int pci_config_write(struct pci_bus *bus, unsigned int devfn,
189                             int where, int size, u32 val)
190 {
191         switch (size) {
192         case 1: 
193                 return write_config_byte(bus, devfn, where, (u8) val);
194         case 2: 
195                 return write_config_word(bus, devfn, where, (u16) val);
196         default:
197                 return write_config_dword(bus, devfn, where, val);
198         }
199 }
200
201 struct pci_ops rc32434_pci_ops = {
202         .read =  pci_config_read,
203         .write = pci_config_write,
204 };