Import changeset
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / kernel / pci.c
1 /*
2  * pci.c - Low-Level PCI Access in IA-64
3  * 
4  * Derived from bios32.c of i386 tree.
5  */
6 #include <linux/config.h>
7
8 #include <linux/types.h>
9 #include <linux/kernel.h>
10 #include <linux/pci.h>
11 #include <linux/init.h>
12 #include <linux/ioport.h>
13 #include <linux/malloc.h>
14 #include <linux/smp_lock.h>
15 #include <linux/spinlock.h>
16
17 #include <asm/machvec.h>
18 #include <asm/page.h>
19 #include <asm/segment.h>
20 #include <asm/system.h>
21 #include <asm/io.h>
22
23 #include <asm/sal.h>
24
25
26 #ifdef CONFIG_SMP
27 # include <asm/smp.h>
28 #endif
29 #include <asm/irq.h>
30
31
32 #undef DEBUG
33 #define DEBUG
34
35 #ifdef DEBUG
36 #define DBG(x...) printk(x)
37 #else
38 #define DBG(x...)
39 #endif
40
41 /*
42  * This interrupt-safe spinlock protects all accesses to PCI
43  * configuration space.
44  */
45 spinlock_t pci_lock = SPIN_LOCK_UNLOCKED;
46
47 struct pci_fixup pcibios_fixups[] = {
48         { 0 }
49 };
50
51 /* Macro to build a PCI configuration address to be passed as a parameter to SAL. */
52
53 #define PCI_CONFIG_ADDRESS(dev, where) \
54         (((u64) dev->bus->number << 16) | ((u64) (dev->devfn & 0xff) << 8) | (where & 0xff))
55
56 static int 
57 pci_conf_read_config_byte(struct pci_dev *dev, int where, u8 *value)
58 {
59         s64 status;
60         u64 lval;
61
62         status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 1, &lval);
63         *value = lval;
64         return status;
65 }
66
67 static int 
68 pci_conf_read_config_word(struct pci_dev *dev, int where, u16 *value)
69 {
70         s64 status;
71         u64 lval;
72
73         status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 2, &lval);
74         *value = lval;
75         return status;
76 }
77
78 static int 
79 pci_conf_read_config_dword(struct pci_dev *dev, int where, u32 *value)
80 {
81         s64 status;
82         u64 lval;
83
84         status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 4, &lval);
85         *value = lval;
86         return status;
87 }
88
89 static int 
90 pci_conf_write_config_byte (struct pci_dev *dev, int where, u8 value)
91 {
92         return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS(dev, where), 1, value);
93 }
94
95 static int 
96 pci_conf_write_config_word (struct pci_dev *dev, int where, u16 value)
97 {
98         return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS(dev, where), 2, value);
99 }
100
101 static int 
102 pci_conf_write_config_dword (struct pci_dev *dev, int where, u32 value)
103 {
104         return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS(dev, where), 4, value);
105 }
106
107 struct pci_ops pci_conf = {
108       pci_conf_read_config_byte,
109       pci_conf_read_config_word,
110       pci_conf_read_config_dword,
111       pci_conf_write_config_byte,
112       pci_conf_write_config_word,
113       pci_conf_write_config_dword
114 };
115
116 /*
117  * Initialization. Uses the SAL interface
118  */
119 void __init 
120 pcibios_init (void)
121 {
122 #       define PCI_BUSES_TO_SCAN 255
123         int i;
124
125         platform_pci_fixup(0);  /* phase 0 initialization (before PCI bus has been scanned) */
126
127         printk("PCI: Probing PCI hardware\n");
128         for (i = 0; i < PCI_BUSES_TO_SCAN; i++) 
129                 pci_scan_bus(i, &pci_conf, NULL);
130
131         platform_pci_fixup(1);  /* phase 1 initialization (after PCI bus has been scanned) */
132         return;
133 }
134
135 /*
136  *  Called after each bus is probed, but before its children
137  *  are examined.
138  */
139 void __init
140 pcibios_fixup_bus (struct pci_bus *b)
141 {
142         return;
143 }
144
145 void __init
146 pcibios_update_resource (struct pci_dev *dev, struct resource *root,
147                          struct resource *res, int resource)
148 {
149         unsigned long where, size;
150         u32 reg;
151
152         where = PCI_BASE_ADDRESS_0 + (resource * 4);
153         size = res->end - res->start;
154         pci_read_config_dword(dev, where, &reg);
155         reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
156         pci_write_config_dword(dev, where, reg);
157
158         /* ??? FIXME -- record old value for shutdown.  */
159 }
160
161 void __init
162 pcibios_update_irq (struct pci_dev *dev, int irq)
163 {
164         pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
165
166         /* ??? FIXME -- record old value for shutdown.  */
167 }
168
169 void __init
170 pcibios_fixup_pbus_ranges (struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
171 {
172         ranges->io_start -= bus->resource[0]->start;
173         ranges->io_end -= bus->resource[0]->start;
174         ranges->mem_start -= bus->resource[1]->start;
175         ranges->mem_end -= bus->resource[1]->start;
176 }
177
178 int
179 pcibios_enable_device (struct pci_dev *dev)
180 {
181         /* Not needed, since we enable all devices at startup.  */
182         return 0;
183 }
184
185 void
186 pcibios_align_resource (void *data, struct resource *res, unsigned long size)
187 {
188 }
189
190 /*
191  * PCI BIOS setup, always defaults to SAL interface
192  */
193 char * __init 
194 pcibios_setup (char *str)
195 {
196         return NULL;
197 }