aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers/pci/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/drivers/pci/pci.c')
-rw-r--r--arch/sh/drivers/pci/pci.c223
1 files changed, 150 insertions, 73 deletions
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 9a1c423ad167..a09c77dd09db 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -19,6 +19,7 @@
19#include <linux/dma-debug.h> 19#include <linux/dma-debug.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/mutex.h> 21#include <linux/mutex.h>
22#include <linux/spinlock.h>
22 23
23unsigned long PCIBIOS_MIN_IO = 0x0000; 24unsigned long PCIBIOS_MIN_IO = 0x0000;
24unsigned long PCIBIOS_MIN_MEM = 0; 25unsigned long PCIBIOS_MIN_MEM = 0;
@@ -33,15 +34,22 @@ static int pci_initialized;
33static void __devinit pcibios_scanbus(struct pci_channel *hose) 34static void __devinit pcibios_scanbus(struct pci_channel *hose)
34{ 35{
35 static int next_busno; 36 static int next_busno;
37 static int need_domain_info;
36 struct pci_bus *bus; 38 struct pci_bus *bus;
37 39
38 bus = pci_scan_bus(next_busno, hose->pci_ops, hose); 40 bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
41 hose->bus = bus;
42
43 need_domain_info = need_domain_info || hose->index;
44 hose->need_domain_info = need_domain_info;
39 if (bus) { 45 if (bus) {
40 next_busno = bus->subordinate + 1; 46 next_busno = bus->subordinate + 1;
41 /* Don't allow 8-bit bus number overflow inside the hose - 47 /* Don't allow 8-bit bus number overflow inside the hose -
42 reserve some space for bridges. */ 48 reserve some space for bridges. */
43 if (next_busno > 224) 49 if (next_busno > 224) {
44 next_busno = 0; 50 next_busno = 0;
51 need_domain_info = 1;
52 }
45 53
46 pci_bus_size_bridges(bus); 54 pci_bus_size_bridges(bus);
47 pci_bus_assign_resources(bus); 55 pci_bus_assign_resources(bus);
@@ -49,12 +57,28 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
49 } 57 }
50} 58}
51 59
60/*
61 * This interrupt-safe spinlock protects all accesses to PCI
62 * configuration space.
63 */
64DEFINE_RAW_SPINLOCK(pci_config_lock);
52static DEFINE_MUTEX(pci_scan_mutex); 65static DEFINE_MUTEX(pci_scan_mutex);
53 66
54void __devinit register_pci_controller(struct pci_channel *hose) 67int __devinit register_pci_controller(struct pci_channel *hose)
55{ 68{
56 request_resource(&iomem_resource, hose->mem_resource); 69 int i;
57 request_resource(&ioport_resource, hose->io_resource); 70
71 for (i = 0; i < hose->nr_resources; i++) {
72 struct resource *res = hose->resources + i;
73
74 if (res->flags & IORESOURCE_IO) {
75 if (request_resource(&ioport_resource, res) < 0)
76 goto out;
77 } else {
78 if (request_resource(&iomem_resource, res) < 0)
79 goto out;
80 }
81 }
58 82
59 *hose_tail = hose; 83 *hose_tail = hose;
60 hose_tail = &hose->next; 84 hose_tail = &hose->next;
@@ -68,6 +92,11 @@ void __devinit register_pci_controller(struct pci_channel *hose)
68 } 92 }
69 93
70 /* 94 /*
95 * Setup the ERR/PERR and SERR timers, if available.
96 */
97 pcibios_enable_timers(hose);
98
99 /*
71 * Scan the bus if it is register after the PCI subsystem 100 * Scan the bus if it is register after the PCI subsystem
72 * initialization. 101 * initialization.
73 */ 102 */
@@ -76,6 +105,15 @@ void __devinit register_pci_controller(struct pci_channel *hose)
76 pcibios_scanbus(hose); 105 pcibios_scanbus(hose);
77 mutex_unlock(&pci_scan_mutex); 106 mutex_unlock(&pci_scan_mutex);
78 } 107 }
108
109 return 0;
110
111out:
112 for (--i; i >= 0; i--)
113 release_resource(&hose->resources[i]);
114
115 printk(KERN_WARNING "Skipping PCI bus scan due to resource conflict\n");
116 return -1;
79} 117}
80 118
81static int __init pcibios_init(void) 119static int __init pcibios_init(void)
@@ -107,8 +145,6 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev,
107 for (i = 0; i < PCI_NUM_RESOURCES; i++) { 145 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
108 if (!dev->resource[i].start) 146 if (!dev->resource[i].start)
109 continue; 147 continue;
110 if (dev->resource[i].flags & IORESOURCE_PCI_FIXED)
111 continue;
112 if (dev->resource[i].flags & IORESOURCE_IO) 148 if (dev->resource[i].flags & IORESOURCE_IO)
113 offset = hose->io_offset; 149 offset = hose->io_offset;
114 else if (dev->resource[i].flags & IORESOURCE_MEM) 150 else if (dev->resource[i].flags & IORESOURCE_MEM)
@@ -127,11 +163,13 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
127{ 163{
128 struct pci_dev *dev = bus->self; 164 struct pci_dev *dev = bus->self;
129 struct list_head *ln; 165 struct list_head *ln;
130 struct pci_channel *chan = bus->sysdata; 166 struct pci_channel *hose = bus->sysdata;
131 167
132 if (!dev) { 168 if (!dev) {
133 bus->resource[0] = chan->io_resource; 169 int i;
134 bus->resource[1] = chan->mem_resource; 170
171 for (i = 0; i < hose->nr_resources; i++)
172 bus->resource[i] = hose->resources + i;
135 } 173 }
136 174
137 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { 175 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
@@ -148,34 +186,29 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
148 * addresses to be allocated in the 0x000-0x0ff region 186 * addresses to be allocated in the 0x000-0x0ff region
149 * modulo 0x400. 187 * modulo 0x400.
150 */ 188 */
151void pcibios_align_resource(void *data, struct resource *res, 189resource_size_t pcibios_align_resource(void *data, const struct resource *res,
152 resource_size_t size, resource_size_t align) 190 resource_size_t size, resource_size_t align)
153{ 191{
154 struct pci_dev *dev = data; 192 struct pci_dev *dev = data;
155 struct pci_channel *chan = dev->sysdata; 193 struct pci_channel *hose = dev->sysdata;
156 resource_size_t start = res->start; 194 resource_size_t start = res->start;
157 195
158 if (res->flags & IORESOURCE_IO) { 196 if (res->flags & IORESOURCE_IO) {
159 if (start < PCIBIOS_MIN_IO + chan->io_resource->start) 197 if (start < PCIBIOS_MIN_IO + hose->resources[0].start)
160 start = PCIBIOS_MIN_IO + chan->io_resource->start; 198 start = PCIBIOS_MIN_IO + hose->resources[0].start;
161 199
162 /* 200 /*
163 * Put everything into 0x00-0xff region modulo 0x400. 201 * Put everything into 0x00-0xff region modulo 0x400.
164 */ 202 */
165 if (start & 0x300) { 203 if (start & 0x300)
166 start = (start + 0x3ff) & ~0x3ff; 204 start = (start + 0x3ff) & ~0x3ff;
167 res->start = start;
168 }
169 } else if (res->flags & IORESOURCE_MEM) {
170 if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start)
171 start = PCIBIOS_MIN_MEM + chan->mem_resource->start;
172 } 205 }
173 206
174 res->start = start; 207 return start;
175} 208}
176 209
177void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, 210void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
178 struct resource *res) 211 struct resource *res)
179{ 212{
180 struct pci_channel *hose = dev->sysdata; 213 struct pci_channel *hose = dev->sysdata;
181 unsigned long offset = 0; 214 unsigned long offset = 0;
@@ -189,9 +222,8 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
189 region->end = res->end - offset; 222 region->end = res->end - offset;
190} 223}
191 224
192void __devinit 225void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
193pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 226 struct pci_bus_region *region)
194 struct pci_bus_region *region)
195{ 227{
196 struct pci_channel *hose = dev->sysdata; 228 struct pci_channel *hose = dev->sysdata;
197 unsigned long offset = 0; 229 unsigned long offset = 0;
@@ -207,40 +239,7 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
207 239
208int pcibios_enable_device(struct pci_dev *dev, int mask) 240int pcibios_enable_device(struct pci_dev *dev, int mask)
209{ 241{
210 u16 cmd, old_cmd; 242 return pci_enable_resources(dev, mask);
211 int idx;
212 struct resource *r;
213
214 pci_read_config_word(dev, PCI_COMMAND, &cmd);
215 old_cmd = cmd;
216 for (idx=0; idx < PCI_NUM_RESOURCES; idx++) {
217 /* Only set up the requested stuff */
218 if (!(mask & (1<<idx)))
219 continue;
220
221 r = &dev->resource[idx];
222 if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
223 continue;
224 if ((idx == PCI_ROM_RESOURCE) &&
225 (!(r->flags & IORESOURCE_ROM_ENABLE)))
226 continue;
227 if (!r->start && r->end) {
228 printk(KERN_ERR "PCI: Device %s not available "
229 "because of resource collisions\n",
230 pci_name(dev));
231 return -EINVAL;
232 }
233 if (r->flags & IORESOURCE_IO)
234 cmd |= PCI_COMMAND_IO;
235 if (r->flags & IORESOURCE_MEM)
236 cmd |= PCI_COMMAND_MEMORY;
237 }
238 if (cmd != old_cmd) {
239 printk("PCI: Enabling device %s (%04x -> %04x)\n",
240 pci_name(dev), old_cmd, cmd);
241 pci_write_config_word(dev, PCI_COMMAND, cmd);
242 }
243 return 0;
244} 243}
245 244
246/* 245/*
@@ -269,11 +268,91 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
269 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); 268 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
270} 269}
271 270
272char * __devinit pcibios_setup(char *str) 271char * __devinit __weak pcibios_setup(char *str)
273{ 272{
274 return str; 273 return str;
275} 274}
276 275
276static void __init
277pcibios_bus_report_status_early(struct pci_channel *hose,
278 int top_bus, int current_bus,
279 unsigned int status_mask, int warn)
280{
281 unsigned int pci_devfn;
282 u16 status;
283 int ret;
284
285 for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
286 if (PCI_FUNC(pci_devfn))
287 continue;
288 ret = early_read_config_word(hose, top_bus, current_bus,
289 pci_devfn, PCI_STATUS, &status);
290 if (ret != PCIBIOS_SUCCESSFUL)
291 continue;
292 if (status == 0xffff)
293 continue;
294
295 early_write_config_word(hose, top_bus, current_bus,
296 pci_devfn, PCI_STATUS,
297 status & status_mask);
298 if (warn)
299 printk("(%02x:%02x: %04X) ", current_bus,
300 pci_devfn, status);
301 }
302}
303
304/*
305 * We can't use pci_find_device() here since we are
306 * called from interrupt context.
307 */
308static void __init_refok
309pcibios_bus_report_status(struct pci_bus *bus, unsigned int status_mask,
310 int warn)
311{
312 struct pci_dev *dev;
313
314 list_for_each_entry(dev, &bus->devices, bus_list) {
315 u16 status;
316
317 /*
318 * ignore host bridge - we handle
319 * that separately
320 */
321 if (dev->bus->number == 0 && dev->devfn == 0)
322 continue;
323
324 pci_read_config_word(dev, PCI_STATUS, &status);
325 if (status == 0xffff)
326 continue;
327
328 if ((status & status_mask) == 0)
329 continue;
330
331 /* clear the status errors */
332 pci_write_config_word(dev, PCI_STATUS, status & status_mask);
333
334 if (warn)
335 printk("(%s: %04X) ", pci_name(dev), status);
336 }
337
338 list_for_each_entry(dev, &bus->devices, bus_list)
339 if (dev->subordinate)
340 pcibios_bus_report_status(dev->subordinate, status_mask, warn);
341}
342
343void __init_refok pcibios_report_status(unsigned int status_mask, int warn)
344{
345 struct pci_channel *hose;
346
347 for (hose = hose_head; hose; hose = hose->next) {
348 if (unlikely(!hose->bus))
349 pcibios_bus_report_status_early(hose, hose_head->index,
350 hose->index, status_mask, warn);
351 else
352 pcibios_bus_report_status(hose->bus, status_mask, warn);
353 }
354}
355
277int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, 356int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
278 enum pci_mmap_state mmap_state, int write_combine) 357 enum pci_mmap_state mmap_state, int write_combine)
279{ 358{
@@ -295,13 +374,20 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
295 vma->vm_page_prot); 374 vma->vm_page_prot);
296} 375}
297 376
377#ifndef CONFIG_GENERIC_IOMAP
378
298static void __iomem *ioport_map_pci(struct pci_dev *dev, 379static void __iomem *ioport_map_pci(struct pci_dev *dev,
299 unsigned long port, unsigned int nr) 380 unsigned long port, unsigned int nr)
300{ 381{
301 struct pci_channel *chan = dev->sysdata; 382 struct pci_channel *chan = dev->sysdata;
302 383
303 if (!chan->io_map_base) 384 if (unlikely(!chan->io_map_base)) {
304 chan->io_map_base = generic_io_base; 385 chan->io_map_base = sh_io_port_base;
386
387 if (pci_domains_supported)
388 panic("To avoid data corruption io_map_base MUST be "
389 "set with multiple PCI domains.");
390 }
305 391
306 return (void __iomem *)(chan->io_map_base + port); 392 return (void __iomem *)(chan->io_map_base + port);
307} 393}
@@ -319,20 +405,9 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
319 405
320 if (flags & IORESOURCE_IO) 406 if (flags & IORESOURCE_IO)
321 return ioport_map_pci(dev, start, len); 407 return ioport_map_pci(dev, start, len);
322
323 /*
324 * Presently the IORESOURCE_MEM case is a bit special, most
325 * SH7751 style PCI controllers have PCI memory at a fixed
326 * location in the address space where no remapping is desired.
327 * With the IORESOURCE_MEM case more care has to be taken
328 * to inhibit page table mapping for legacy cores, but this is
329 * punted off to __ioremap().
330 * -- PFM.
331 */
332 if (flags & IORESOURCE_MEM) { 408 if (flags & IORESOURCE_MEM) {
333 if (flags & IORESOURCE_CACHEABLE) 409 if (flags & IORESOURCE_CACHEABLE)
334 return ioremap(start, len); 410 return ioremap(start, len);
335
336 return ioremap_nocache(start, len); 411 return ioremap_nocache(start, len);
337 } 412 }
338 413
@@ -346,6 +421,8 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
346} 421}
347EXPORT_SYMBOL(pci_iounmap); 422EXPORT_SYMBOL(pci_iounmap);
348 423
424#endif /* CONFIG_GENERIC_IOMAP */
425
349#ifdef CONFIG_HOTPLUG 426#ifdef CONFIG_HOTPLUG
350EXPORT_SYMBOL(pcibios_resource_to_bus); 427EXPORT_SYMBOL(pcibios_resource_to_bus);
351EXPORT_SYMBOL(pcibios_bus_to_resource); 428EXPORT_SYMBOL(pcibios_bus_to_resource);