sh: pci: Consolidate the remaining common bits.
[pandora-kernel.git] / arch / sh / drivers / pci / pci-new.c
1 /*
2  * New-style PCI core.
3  *
4  * Copyright (c) 2002  M. R. Brown
5  * Copyright (c) 2004 - 2009  Paul Mundt
6  *
7  * This file is subject to the terms and conditions of the GNU General Public
8  * License.  See the file "COPYING" in the main directory of this archive
9  * for more details.
10  */
11 #include <linux/kernel.h>
12 #include <linux/pci.h>
13 #include <linux/init.h>
14 #include <linux/dma-debug.h>
15 #include <linux/io.h>
16 #include <linux/mutex.h>
17
18 /*
19  * The PCI controller list.
20  */
21 static struct pci_channel *hose_head, **hose_tail = &hose_head;
22
23 static int pci_initialized;
24
25 static void __devinit pcibios_scanbus(struct pci_channel *hose)
26 {
27         static int next_busno;
28         struct pci_bus *bus;
29
30         /* Catch botched conversion attempts */
31         BUG_ON(hose->init);
32
33         bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
34         if (bus) {
35                 next_busno = bus->subordinate + 1;
36                 /* Don't allow 8-bit bus number overflow inside the hose -
37                    reserve some space for bridges. */
38                 if (next_busno > 224)
39                         next_busno = 0;
40
41                 pci_bus_size_bridges(bus);
42                 pci_bus_assign_resources(bus);
43                 pci_enable_bridges(bus);
44         }
45 }
46
47 static DEFINE_MUTEX(pci_scan_mutex);
48
49 void __devinit register_pci_controller(struct pci_channel *hose)
50 {
51         if (request_resource(&iomem_resource, hose->mem_resource) < 0)
52                 goto out;
53         if (request_resource(&ioport_resource, hose->io_resource) < 0) {
54                 release_resource(hose->mem_resource);
55                 goto out;
56         }
57
58         *hose_tail = hose;
59         hose_tail = &hose->next;
60
61         /*
62          * Do not panic here but later - this might hapen before console init.
63          */
64         if (!hose->io_map_base) {
65                 printk(KERN_WARNING
66                        "registering PCI controller with io_map_base unset\n");
67         }
68
69         /*
70          * Scan the bus if it is register after the PCI subsystem
71          * initialization.
72          */
73         if (pci_initialized) {
74                 mutex_lock(&pci_scan_mutex);
75                 pcibios_scanbus(hose);
76                 mutex_unlock(&pci_scan_mutex);
77         }
78
79         return;
80
81 out:
82         printk(KERN_WARNING
83                "Skipping PCI bus scan due to resource conflict\n");
84 }
85
86 static int __init pcibios_init(void)
87 {
88         struct pci_channel *hose;
89
90         /* Scan all of the recorded PCI controllers.  */
91         for (hose = hose_head; hose; hose = hose->next)
92                 pcibios_scanbus(hose);
93
94         pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
95
96         dma_debug_add_bus(&pci_bus_type);
97
98         pci_initialized = 1;
99
100         return 0;
101 }
102 subsys_initcall(pcibios_init);
103
104 static void pcibios_fixup_device_resources(struct pci_dev *dev,
105         struct pci_bus *bus)
106 {
107         /* Update device resources.  */
108         struct pci_channel *hose = bus->sysdata;
109         unsigned long offset = 0;
110         int i;
111
112         for (i = 0; i < PCI_NUM_RESOURCES; i++) {
113                 if (!dev->resource[i].start)
114                         continue;
115                 if (dev->resource[i].flags & IORESOURCE_PCI_FIXED)
116                         continue;
117                 if (dev->resource[i].flags & IORESOURCE_IO)
118                         offset = hose->io_offset;
119                 else if (dev->resource[i].flags & IORESOURCE_MEM)
120                         offset = hose->mem_offset;
121
122                 dev->resource[i].start += offset;
123                 dev->resource[i].end += offset;
124         }
125 }
126
127 /*
128  *  Called after each bus is probed, but before its children
129  *  are examined.
130  */
131 void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus)
132 {
133         struct pci_dev *dev = bus->self;
134         struct list_head *ln;
135         struct pci_channel *chan = bus->sysdata;
136
137         if (!dev) {
138                 bus->resource[0] = chan->io_resource;
139                 bus->resource[1] = chan->mem_resource;
140         }
141
142         for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
143                 dev = pci_dev_b(ln);
144
145                 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
146                         pcibios_fixup_device_resources(dev, bus);
147         }
148 }