1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/types.h>
25#include <linux/pci.h>
26#include <linux/kernel.h>
27
28#include <asm/mips-boards/msc01_pci.h>
29
30#define PCI_ACCESS_READ 0
31#define PCI_ACCESS_WRITE 1
32
33
34
35
36
37#define PCI_CFG_TYPE0_REG_SHF 0
38#define PCI_CFG_TYPE0_FUNC_SHF 8
39
40
41#define PCI_CFG_TYPE1_REG_SHF 0
42#define PCI_CFG_TYPE1_FUNC_SHF 8
43#define PCI_CFG_TYPE1_DEV_SHF 11
44#define PCI_CFG_TYPE1_BUS_SHF 16
45
46static int msc_pcibios_config_access(unsigned char access_type,
47 struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
48{
49 unsigned char busnum = bus->number;
50 u32 intr;
51
52
53 MSC_WRITE(MSC01_PCI_INTSTAT,
54 (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
55
56 MSC_WRITE(MSC01_PCI_CFGADDR,
57 ((busnum << MSC01_PCI_CFGADDR_BNUM_SHF) |
58 (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF) |
59 (PCI_FUNC(devfn) << MSC01_PCI_CFGADDR_FNUM_SHF) |
60 ((where / 4) << MSC01_PCI_CFGADDR_RNUM_SHF)));
61
62
63 if (access_type == PCI_ACCESS_WRITE)
64 MSC_WRITE(MSC01_PCI_CFGDATA, *data);
65 else
66 MSC_READ(MSC01_PCI_CFGDATA, *data);
67
68
69 MSC_READ(MSC01_PCI_INTSTAT, intr);
70 if (intr & (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)) {
71
72
73
74 MSC_WRITE(MSC01_PCI_INTSTAT,
75 (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
76
77 return -1;
78 }
79
80 return 0;
81}
82
83
84
85
86
87
88static int msc_pcibios_read(struct pci_bus *bus, unsigned int devfn,
89 int where, int size, u32 * val)
90{
91 u32 data = 0;
92
93 if ((size == 2) && (where & 1))
94 return PCIBIOS_BAD_REGISTER_NUMBER;
95 else if ((size == 4) && (where & 3))
96 return PCIBIOS_BAD_REGISTER_NUMBER;
97
98 if (msc_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
99 &data))
100 return -1;
101
102 if (size == 1)
103 *val = (data >> ((where & 3) << 3)) & 0xff;
104 else if (size == 2)
105 *val = (data >> ((where & 3) << 3)) & 0xffff;
106 else
107 *val = data;
108
109 return PCIBIOS_SUCCESSFUL;
110}
111
112static int msc_pcibios_write(struct pci_bus *bus, unsigned int devfn,
113 int where, int size, u32 val)
114{
115 u32 data = 0;
116
117 if ((size == 2) && (where & 1))
118 return PCIBIOS_BAD_REGISTER_NUMBER;
119 else if ((size == 4) && (where & 3))
120 return PCIBIOS_BAD_REGISTER_NUMBER;
121
122 if (size == 4)
123 data = val;
124 else {
125 if (msc_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
126 where, &data))
127 return -1;
128
129 if (size == 1)
130 data = (data & ~(0xff << ((where & 3) << 3))) |
131 (val << ((where & 3) << 3));
132 else if (size == 2)
133 data = (data & ~(0xffff << ((where & 3) << 3))) |
134 (val << ((where & 3) << 3));
135 }
136
137 if (msc_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
138 &data))
139 return -1;
140
141 return PCIBIOS_SUCCESSFUL;
142}
143
144struct pci_ops msc_pci_ops = {
145 .read = msc_pcibios_read,
146 .write = msc_pcibios_write
147};
148