diff options
Diffstat (limited to 'arch/mips/pci/ops-tx4938.c')
-rw-r--r-- | arch/mips/pci/ops-tx4938.c | 80 |
1 files changed, 48 insertions, 32 deletions
diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c index 445007084515..a450c4062031 100644 --- a/arch/mips/pci/ops-tx4938.c +++ b/arch/mips/pci/ops-tx4938.c | |||
@@ -46,50 +46,63 @@ struct resource tx4938_pcic1_pci_mem_resource = { | |||
46 | .flags = IORESOURCE_MEM | 46 | .flags = IORESOURCE_MEM |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static int mkaddr(int bus, int dev_fn, int where, int *flagsp) | 49 | static int mkaddr(int bus, int dev_fn, int where, |
50 | struct tx4938_pcic_reg *pcicptr) | ||
50 | { | 51 | { |
51 | if (bus > 0) { | 52 | if (bus > 0) { |
52 | /* Type 1 configuration */ | 53 | /* Type 1 configuration */ |
53 | tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | | 54 | pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | |
54 | ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; | 55 | ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; |
55 | } else { | 56 | } else { |
56 | if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0)) | 57 | if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0)) |
57 | return -1; | 58 | return -1; |
58 | 59 | ||
59 | /* Type 0 configuration */ | 60 | /* Type 0 configuration */ |
60 | tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | | 61 | pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | |
61 | ((dev_fn & 0xff) << 0x08) | (where & 0xfc); | 62 | ((dev_fn & 0xff) << 0x08) | (where & 0xfc); |
62 | } | 63 | } |
63 | /* clear M_ABORT and Disable M_ABORT Int. */ | 64 | /* clear M_ABORT and Disable M_ABORT Int. */ |
64 | tx4938_pcicptr->pcistatus = | 65 | pcicptr->pcistatus = |
65 | (tx4938_pcicptr->pcistatus & 0x0000ffff) | | 66 | (pcicptr->pcistatus & 0x0000ffff) | |
66 | (PCI_STATUS_REC_MASTER_ABORT << 16); | 67 | (PCI_STATUS_REC_MASTER_ABORT << 16); |
67 | tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; | 68 | pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; |
68 | 69 | ||
69 | return 0; | 70 | return 0; |
70 | } | 71 | } |
71 | 72 | ||
72 | static int check_abort(int flags) | 73 | static int check_abort(struct tx4938_pcic_reg *pcicptr) |
73 | { | 74 | { |
74 | int code = PCIBIOS_SUCCESSFUL; | 75 | int code = PCIBIOS_SUCCESSFUL; |
75 | /* wait write cycle completion before checking error status */ | 76 | /* wait write cycle completion before checking error status */ |
76 | while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB) | 77 | while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB) |
77 | ; | 78 | ; |
78 | if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { | 79 | if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { |
79 | tx4938_pcicptr->pcistatus = | 80 | pcicptr->pcistatus = |
80 | (tx4938_pcicptr-> | 81 | (pcicptr-> |
81 | pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT | 82 | pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT |
82 | << 16); | 83 | << 16); |
83 | tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; | 84 | pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; |
84 | code = PCIBIOS_DEVICE_NOT_FOUND; | 85 | code = PCIBIOS_DEVICE_NOT_FOUND; |
85 | } | 86 | } |
86 | return code; | 87 | return code; |
87 | } | 88 | } |
88 | 89 | ||
90 | extern struct pci_controller tx4938_pci_controller[]; | ||
91 | extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch); | ||
92 | |||
93 | static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus) | ||
94 | { | ||
95 | struct pci_controller *channel = bus->sysdata; | ||
96 | return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]); | ||
97 | } | ||
98 | |||
89 | static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, | 99 | static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, |
90 | int where, int size, u32 * val) | 100 | int where, int size, u32 * val) |
91 | { | 101 | { |
92 | int flags, retval, dev, busno, func; | 102 | int retval, dev, busno, func; |
103 | struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus); | ||
104 | void __iomem *cfgdata = | ||
105 | (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata; | ||
93 | 106 | ||
94 | dev = PCI_SLOT(devfn); | 107 | dev = PCI_SLOT(devfn); |
95 | func = PCI_FUNC(devfn); | 108 | func = PCI_FUNC(devfn); |
@@ -101,32 +114,32 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, | |||
101 | busno = 0; | 114 | busno = 0; |
102 | } | 115 | } |
103 | 116 | ||
104 | if (mkaddr(busno, devfn, where, &flags)) | 117 | if (mkaddr(busno, devfn, where, pcicptr)) |
105 | return -1; | 118 | return -1; |
106 | 119 | ||
107 | switch (size) { | 120 | switch (size) { |
108 | case 1: | 121 | case 1: |
109 | *val = *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata | | ||
110 | #ifdef __BIG_ENDIAN | 122 | #ifdef __BIG_ENDIAN |
111 | ((where & 3) ^ 3)); | 123 | cfgdata += (where & 3) ^ 3; |
112 | #else | 124 | #else |
113 | (where & 3)); | 125 | cfgdata += where & 3; |
114 | #endif | 126 | #endif |
127 | *val = __raw_readb(cfgdata); | ||
115 | break; | 128 | break; |
116 | case 2: | 129 | case 2: |
117 | *val = *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata | | ||
118 | #ifdef __BIG_ENDIAN | 130 | #ifdef __BIG_ENDIAN |
119 | ((where & 3) ^ 2)); | 131 | cfgdata += (where & 2) ^ 2; |
120 | #else | 132 | #else |
121 | (where & 3)); | 133 | cfgdata += where & 2; |
122 | #endif | 134 | #endif |
135 | *val = __raw_readw(cfgdata); | ||
123 | break; | 136 | break; |
124 | case 4: | 137 | case 4: |
125 | *val = tx4938_pcicptr->g2pcfgdata; | 138 | *val = __raw_readl(cfgdata); |
126 | break; | 139 | break; |
127 | } | 140 | } |
128 | 141 | ||
129 | retval = check_abort(flags); | 142 | retval = check_abort(pcicptr); |
130 | if (retval == PCIBIOS_DEVICE_NOT_FOUND) | 143 | if (retval == PCIBIOS_DEVICE_NOT_FOUND) |
131 | *val = 0xffffffff; | 144 | *val = 0xffffffff; |
132 | 145 | ||
@@ -136,7 +149,10 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, | |||
136 | static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where, | 149 | static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where, |
137 | int size, u32 val) | 150 | int size, u32 val) |
138 | { | 151 | { |
139 | int flags, dev, busno, func; | 152 | int dev, busno, func; |
153 | struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus); | ||
154 | void __iomem *cfgdata = | ||
155 | (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata; | ||
140 | 156 | ||
141 | busno = bus->number; | 157 | busno = bus->number; |
142 | dev = PCI_SLOT(devfn); | 158 | dev = PCI_SLOT(devfn); |
@@ -149,32 +165,32 @@ static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, | |||
149 | busno = 0; | 165 | busno = 0; |
150 | } | 166 | } |
151 | 167 | ||
152 | if (mkaddr(busno, devfn, where, &flags)) | 168 | if (mkaddr(busno, devfn, where, pcicptr)) |
153 | return -1; | 169 | return -1; |
154 | 170 | ||
155 | switch (size) { | 171 | switch (size) { |
156 | case 1: | 172 | case 1: |
157 | *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata | | ||
158 | #ifdef __BIG_ENDIAN | 173 | #ifdef __BIG_ENDIAN |
159 | ((where & 3) ^ 3)) = val; | 174 | cfgdata += (where & 3) ^ 3; |
160 | #else | 175 | #else |
161 | (where & 3)) = val; | 176 | cfgdata += where & 3; |
162 | #endif | 177 | #endif |
178 | __raw_writeb(val, cfgdata); | ||
163 | break; | 179 | break; |
164 | case 2: | 180 | case 2: |
165 | *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata | | ||
166 | #ifdef __BIG_ENDIAN | 181 | #ifdef __BIG_ENDIAN |
167 | ((where & 0x3) ^ 0x2)) = val; | 182 | cfgdata += (where & 2) ^ 2; |
168 | #else | 183 | #else |
169 | (where & 3)) = val; | 184 | cfgdata += where & 2; |
170 | #endif | 185 | #endif |
186 | __raw_writew(val, cfgdata); | ||
171 | break; | 187 | break; |
172 | case 4: | 188 | case 4: |
173 | tx4938_pcicptr->g2pcfgdata = val; | 189 | __raw_writel(val, cfgdata); |
174 | break; | 190 | break; |
175 | } | 191 | } |
176 | 192 | ||
177 | return check_abort(flags); | 193 | return check_abort(pcicptr); |
178 | } | 194 | } |
179 | 195 | ||
180 | struct pci_ops tx4938_pci_ops = { | 196 | struct pci_ops tx4938_pci_ops = { |