aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/pci
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2005-12-06 17:31:30 -0500
committerLen Brown <len.brown@intel.com>2005-12-06 17:31:30 -0500
commit3d5271f9883cba7b54762bc4fe027d4172f06db7 (patch)
treeab8a881a14478598a0c8bda0d26c62cdccfffd6d /arch/ia64/pci
parent378b2556f4e09fa6f87ff0cb5c4395ff28257d02 (diff)
parent9115a6c787596e687df03010d97fccc5e0762506 (diff)
Pull release into acpica branch
Diffstat (limited to 'arch/ia64/pci')
-rw-r--r--arch/ia64/pci/pci.c164
1 files changed, 109 insertions, 55 deletions
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 9b5de589b82f..20d76fae24e8 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -95,7 +95,7 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn,
95} 95}
96 96
97static struct pci_raw_ops pci_sal_ops = { 97static struct pci_raw_ops pci_sal_ops = {
98 .read = pci_sal_read, 98 .read = pci_sal_read,
99 .write = pci_sal_write 99 .write = pci_sal_write
100}; 100};
101 101
@@ -120,29 +120,6 @@ struct pci_ops pci_root_ops = {
120 .write = pci_write, 120 .write = pci_write,
121}; 121};
122 122
123#ifdef CONFIG_NUMA
124extern acpi_status acpi_map_iosapic(acpi_handle, u32, void *, void **);
125static void acpi_map_iosapics(void)
126{
127 acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
128}
129#else
130static void acpi_map_iosapics(void)
131{
132 return;
133}
134#endif /* CONFIG_NUMA */
135
136static int __init
137pci_acpi_init (void)
138{
139 acpi_map_iosapics();
140
141 return 0;
142}
143
144subsys_initcall(pci_acpi_init);
145
146/* Called by ACPI when it finds a new root bus. */ 123/* Called by ACPI when it finds a new root bus. */
147 124
148static struct pci_controller * __devinit 125static struct pci_controller * __devinit
@@ -160,35 +137,121 @@ alloc_pci_controller (int seg)
160 return controller; 137 return controller;
161} 138}
162 139
163static u64 __devinit 140struct pci_root_info {
164add_io_space (struct acpi_resource_address64 *addr) 141 struct pci_controller *controller;
142 char *name;
143};
144
145static unsigned int
146new_space (u64 phys_base, int sparse)
165{ 147{
166 u64 offset; 148 u64 mmio_base;
167 int sparse = 0;
168 int i; 149 int i;
169 150
170 if (addr->address_translation_offset == 0) 151 if (phys_base == 0)
171 return IO_SPACE_BASE(0); /* part of legacy IO space */ 152 return 0; /* legacy I/O port space */
172
173 if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
174 sparse = 1;
175 153
176 offset = (u64) ioremap(addr->address_translation_offset, 0); 154 mmio_base = (u64) ioremap(phys_base, 0);
177 for (i = 0; i < num_io_spaces; i++) 155 for (i = 0; i < num_io_spaces; i++)
178 if (io_space[i].mmio_base == offset && 156 if (io_space[i].mmio_base == mmio_base &&
179 io_space[i].sparse == sparse) 157 io_space[i].sparse == sparse)
180 return IO_SPACE_BASE(i); 158 return i;
181 159
182 if (num_io_spaces == MAX_IO_SPACES) { 160 if (num_io_spaces == MAX_IO_SPACES) {
183 printk("Too many IO port spaces\n"); 161 printk(KERN_ERR "PCI: Too many IO port spaces "
162 "(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
184 return ~0; 163 return ~0;
185 } 164 }
186 165
187 i = num_io_spaces++; 166 i = num_io_spaces++;
188 io_space[i].mmio_base = offset; 167 io_space[i].mmio_base = mmio_base;
189 io_space[i].sparse = sparse; 168 io_space[i].sparse = sparse;
190 169
191 return IO_SPACE_BASE(i); 170 return i;
171}
172
173static u64 __devinit
174add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr)
175{
176 struct resource *resource;
177 char *name;
178 u64 base, min, max, base_port;
179 unsigned int sparse = 0, space_nr, len;
180
181 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
182 if (!resource) {
183 printk(KERN_ERR "PCI: No memory for %s I/O port space\n",
184 info->name);
185 goto out;
186 }
187
188 len = strlen(info->name) + 32;
189 name = kzalloc(len, GFP_KERNEL);
190 if (!name) {
191 printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
192 info->name);
193 goto free_resource;
194 }
195
196 min = addr->min_address_range;
197 max = min + addr->address_length - 1;
198 if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
199 sparse = 1;
200
201 space_nr = new_space(addr->address_translation_offset, sparse);
202 if (space_nr == ~0)
203 goto free_name;
204
205 base = __pa(io_space[space_nr].mmio_base);
206 base_port = IO_SPACE_BASE(space_nr);
207 snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
208 base_port + min, base_port + max);
209
210 /*
211 * The SDM guarantees the legacy 0-64K space is sparse, but if the
212 * mapping is done by the processor (not the bridge), ACPI may not
213 * mark it as sparse.
214 */
215 if (space_nr == 0)
216 sparse = 1;
217
218 resource->name = name;
219 resource->flags = IORESOURCE_MEM;
220 resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
221 resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
222 insert_resource(&iomem_resource, resource);
223
224 return base_port;
225
226free_name:
227 kfree(name);
228free_resource:
229 kfree(resource);
230out:
231 return ~0;
232}
233
234static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
235 struct acpi_resource_address64 *addr)
236{
237 acpi_status status;
238
239 /*
240 * We're only interested in _CRS descriptors that are
241 * - address space descriptors for memory or I/O space
242 * - non-zero size
243 * - producers, i.e., the address space is routed downstream,
244 * not consumed by the bridge itself
245 */
246 status = acpi_resource_to_address64(resource, addr);
247 if (ACPI_SUCCESS(status) &&
248 (addr->resource_type == ACPI_MEMORY_RANGE ||
249 addr->resource_type == ACPI_IO_RANGE) &&
250 addr->address_length &&
251 addr->producer_consumer == ACPI_PRODUCER)
252 return AE_OK;
253
254 return AE_ERROR;
192} 255}
193 256
194static acpi_status __devinit 257static acpi_status __devinit
@@ -198,20 +261,13 @@ count_window (struct acpi_resource *resource, void *data)
198 struct acpi_resource_address64 addr; 261 struct acpi_resource_address64 addr;
199 acpi_status status; 262 acpi_status status;
200 263
201 status = acpi_resource_to_address64(resource, &addr); 264 status = resource_to_window(resource, &addr);
202 if (ACPI_SUCCESS(status)) 265 if (ACPI_SUCCESS(status))
203 if (addr.resource_type == ACPI_MEMORY_RANGE || 266 (*windows)++;
204 addr.resource_type == ACPI_IO_RANGE)
205 (*windows)++;
206 267
207 return AE_OK; 268 return AE_OK;
208} 269}
209 270
210struct pci_root_info {
211 struct pci_controller *controller;
212 char *name;
213};
214
215static __devinit acpi_status add_window(struct acpi_resource *res, void *data) 271static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
216{ 272{
217 struct pci_root_info *info = data; 273 struct pci_root_info *info = data;
@@ -221,13 +277,11 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
221 unsigned long flags, offset = 0; 277 unsigned long flags, offset = 0;
222 struct resource *root; 278 struct resource *root;
223 279
224 status = acpi_resource_to_address64(res, &addr); 280 /* Return AE_OK for non-window resources to keep scanning for more */
281 status = resource_to_window(res, &addr);
225 if (!ACPI_SUCCESS(status)) 282 if (!ACPI_SUCCESS(status))
226 return AE_OK; 283 return AE_OK;
227 284
228 if (!addr.address_length)
229 return AE_OK;
230
231 if (addr.resource_type == ACPI_MEMORY_RANGE) { 285 if (addr.resource_type == ACPI_MEMORY_RANGE) {
232 flags = IORESOURCE_MEM; 286 flags = IORESOURCE_MEM;
233 root = &iomem_resource; 287 root = &iomem_resource;
@@ -235,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
235 } else if (addr.resource_type == ACPI_IO_RANGE) { 289 } else if (addr.resource_type == ACPI_IO_RANGE) {
236 flags = IORESOURCE_IO; 290 flags = IORESOURCE_IO;
237 root = &ioport_resource; 291 root = &ioport_resource;
238 offset = add_io_space(&addr); 292 offset = add_io_space(info, &addr);
239 if (offset == ~0) 293 if (offset == ~0)
240 return AE_OK; 294 return AE_OK;
241 } else 295 } else
@@ -245,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
245 window->resource.name = info->name; 299 window->resource.name = info->name;
246 window->resource.flags = flags; 300 window->resource.flags = flags;
247 window->resource.start = addr.min_address_range + offset; 301 window->resource.start = addr.min_address_range + offset;
248 window->resource.end = addr.max_address_range + offset; 302 window->resource.end = window->resource.start + addr.address_length - 1;
249 window->resource.child = NULL; 303 window->resource.child = NULL;
250 window->offset = offset; 304 window->offset = offset;
251 305
@@ -743,7 +797,7 @@ int pci_vector_resources(int last, int nr_released)
743{ 797{
744 int count = nr_released; 798 int count = nr_released;
745 799
746 count += (IA64_LAST_DEVICE_VECTOR - last); 800 count += (IA64_LAST_DEVICE_VECTOR - last);
747 801
748 return count; 802 return count;
749} 803}