diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/kernel/bios32.c | 5 | ||||
-rw-r--r-- | arch/ia64/kernel/acpi-ext.c | 6 | ||||
-rw-r--r-- | arch/ia64/kernel/acpi.c | 6 | ||||
-rw-r--r-- | arch/ia64/pci/pci.c | 14 | ||||
-rw-r--r-- | arch/x86/Kconfig | 11 | ||||
-rw-r--r-- | arch/x86/include/asm/pci_x86.h | 2 | ||||
-rw-r--r-- | arch/x86/include/uapi/asm/msr-index.h | 5 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 16 | ||||
-rw-r--r-- | arch/x86/pci/acpi.c | 293 | ||||
-rw-r--r-- | arch/x86/pci/bus_numa.c | 4 | ||||
-rw-r--r-- | arch/x86/pci/common.c | 34 | ||||
-rw-r--r-- | arch/x86/pci/intel_mid_pci.c | 4 | ||||
-rw-r--r-- | arch/x86/pci/irq.c | 15 | ||||
-rw-r--r-- | arch/x86/pci/mmconfig-shared.c | 6 |
14 files changed, 157 insertions, 264 deletions
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index ddd75c58b1e8..ab19b7c03423 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -422,17 +422,16 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
422 | static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) | 422 | static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) |
423 | { | 423 | { |
424 | int ret; | 424 | int ret; |
425 | struct pci_host_bridge_window *window; | 425 | struct resource_entry *window; |
426 | 426 | ||
427 | if (list_empty(&sys->resources)) { | 427 | if (list_empty(&sys->resources)) { |
428 | pci_add_resource_offset(&sys->resources, | 428 | pci_add_resource_offset(&sys->resources, |
429 | &iomem_resource, sys->mem_offset); | 429 | &iomem_resource, sys->mem_offset); |
430 | } | 430 | } |
431 | 431 | ||
432 | list_for_each_entry(window, &sys->resources, list) { | 432 | resource_list_for_each_entry(window, &sys->resources) |
433 | if (resource_type(window->res) == IORESOURCE_IO) | 433 | if (resource_type(window->res) == IORESOURCE_IO) |
434 | return 0; | 434 | return 0; |
435 | } | ||
436 | 435 | ||
437 | sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io; | 436 | sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io; |
438 | sys->io_res.end = (busnr + 1) * SZ_64K - 1; | 437 | sys->io_res.end = (busnr + 1) * SZ_64K - 1; |
diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c index 8b9318d311a0..bd09bf74f187 100644 --- a/arch/ia64/kernel/acpi-ext.c +++ b/arch/ia64/kernel/acpi-ext.c | |||
@@ -69,10 +69,10 @@ static acpi_status find_csr_space(struct acpi_resource *resource, void *data) | |||
69 | status = acpi_resource_to_address64(resource, &addr); | 69 | status = acpi_resource_to_address64(resource, &addr); |
70 | if (ACPI_SUCCESS(status) && | 70 | if (ACPI_SUCCESS(status) && |
71 | addr.resource_type == ACPI_MEMORY_RANGE && | 71 | addr.resource_type == ACPI_MEMORY_RANGE && |
72 | addr.address_length && | 72 | addr.address.address_length && |
73 | addr.producer_consumer == ACPI_CONSUMER) { | 73 | addr.producer_consumer == ACPI_CONSUMER) { |
74 | space->base = addr.minimum; | 74 | space->base = addr.address.minimum; |
75 | space->length = addr.address_length; | 75 | space->length = addr.address.address_length; |
76 | return AE_CTRL_TERMINATE; | 76 | return AE_CTRL_TERMINATE; |
77 | } | 77 | } |
78 | return AE_OK; /* keep looking */ | 78 | return AE_OK; /* keep looking */ |
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index e795cb848154..2c4498919d3c 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -380,9 +380,6 @@ static void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
380 | 380 | ||
381 | static int __init acpi_parse_madt(struct acpi_table_header *table) | 381 | static int __init acpi_parse_madt(struct acpi_table_header *table) |
382 | { | 382 | { |
383 | if (!table) | ||
384 | return -EINVAL; | ||
385 | |||
386 | acpi_madt = (struct acpi_table_madt *)table; | 383 | acpi_madt = (struct acpi_table_madt *)table; |
387 | 384 | ||
388 | acpi_madt_rev = acpi_madt->header.revision; | 385 | acpi_madt_rev = acpi_madt->header.revision; |
@@ -645,9 +642,6 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table) | |||
645 | struct acpi_table_header *fadt_header; | 642 | struct acpi_table_header *fadt_header; |
646 | struct acpi_table_fadt *fadt; | 643 | struct acpi_table_fadt *fadt; |
647 | 644 | ||
648 | if (!table) | ||
649 | return -EINVAL; | ||
650 | |||
651 | fadt_header = (struct acpi_table_header *)table; | 645 | fadt_header = (struct acpi_table_header *)table; |
652 | if (fadt_header->revision != 3) | 646 | if (fadt_header->revision != 3) |
653 | return -ENODEV; /* Only deal with ACPI 2.0 FADT */ | 647 | return -ENODEV; /* Only deal with ACPI 2.0 FADT */ |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 900cc93e5409..48cc65705db4 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -188,12 +188,12 @@ static u64 add_io_space(struct pci_root_info *info, | |||
188 | 188 | ||
189 | name = (char *)(iospace + 1); | 189 | name = (char *)(iospace + 1); |
190 | 190 | ||
191 | min = addr->minimum; | 191 | min = addr->address.minimum; |
192 | max = min + addr->address_length - 1; | 192 | max = min + addr->address.address_length - 1; |
193 | if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION) | 193 | if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION) |
194 | sparse = 1; | 194 | sparse = 1; |
195 | 195 | ||
196 | space_nr = new_space(addr->translation_offset, sparse); | 196 | space_nr = new_space(addr->address.translation_offset, sparse); |
197 | if (space_nr == ~0) | 197 | if (space_nr == ~0) |
198 | goto free_resource; | 198 | goto free_resource; |
199 | 199 | ||
@@ -247,7 +247,7 @@ static acpi_status resource_to_window(struct acpi_resource *resource, | |||
247 | if (ACPI_SUCCESS(status) && | 247 | if (ACPI_SUCCESS(status) && |
248 | (addr->resource_type == ACPI_MEMORY_RANGE || | 248 | (addr->resource_type == ACPI_MEMORY_RANGE || |
249 | addr->resource_type == ACPI_IO_RANGE) && | 249 | addr->resource_type == ACPI_IO_RANGE) && |
250 | addr->address_length && | 250 | addr->address.address_length && |
251 | addr->producer_consumer == ACPI_PRODUCER) | 251 | addr->producer_consumer == ACPI_PRODUCER) |
252 | return AE_OK; | 252 | return AE_OK; |
253 | 253 | ||
@@ -284,7 +284,7 @@ static acpi_status add_window(struct acpi_resource *res, void *data) | |||
284 | if (addr.resource_type == ACPI_MEMORY_RANGE) { | 284 | if (addr.resource_type == ACPI_MEMORY_RANGE) { |
285 | flags = IORESOURCE_MEM; | 285 | flags = IORESOURCE_MEM; |
286 | root = &iomem_resource; | 286 | root = &iomem_resource; |
287 | offset = addr.translation_offset; | 287 | offset = addr.address.translation_offset; |
288 | } else if (addr.resource_type == ACPI_IO_RANGE) { | 288 | } else if (addr.resource_type == ACPI_IO_RANGE) { |
289 | flags = IORESOURCE_IO; | 289 | flags = IORESOURCE_IO; |
290 | root = &ioport_resource; | 290 | root = &ioport_resource; |
@@ -297,8 +297,8 @@ static acpi_status add_window(struct acpi_resource *res, void *data) | |||
297 | resource = &info->res[info->res_num]; | 297 | resource = &info->res[info->res_num]; |
298 | resource->name = info->name; | 298 | resource->name = info->name; |
299 | resource->flags = flags; | 299 | resource->flags = flags; |
300 | resource->start = addr.minimum + offset; | 300 | resource->start = addr.address.minimum + offset; |
301 | resource->end = resource->start + addr.address_length - 1; | 301 | resource->end = resource->start + addr.address.address_length - 1; |
302 | info->res_offset[info->res_num] = offset; | 302 | info->res_offset[info->res_num] = offset; |
303 | 303 | ||
304 | if (insert_resource(root, resource)) { | 304 | if (insert_resource(root, resource)) { |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5e28e2be3a41..019f4e5c2b75 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -497,6 +497,17 @@ config X86_INTEL_LPSS | |||
497 | things like clock tree (common clock framework) and pincontrol | 497 | things like clock tree (common clock framework) and pincontrol |
498 | which are needed by the LPSS peripheral drivers. | 498 | which are needed by the LPSS peripheral drivers. |
499 | 499 | ||
500 | config X86_AMD_PLATFORM_DEVICE | ||
501 | bool "AMD ACPI2Platform devices support" | ||
502 | depends on ACPI | ||
503 | select COMMON_CLK | ||
504 | select PINCTRL | ||
505 | ---help--- | ||
506 | Select to interpret AMD specific ACPI device to platform device | ||
507 | such as I2C, UART, GPIO found on AMD Carrizo and later chipsets. | ||
508 | I2C and UART depend on COMMON_CLK to set clock. GPIO driver is | ||
509 | implemented under PINCTRL subsystem. | ||
510 | |||
500 | config IOSF_MBI | 511 | config IOSF_MBI |
501 | tristate "Intel SoC IOSF Sideband support for SoC platforms" | 512 | tristate "Intel SoC IOSF Sideband support for SoC platforms" |
502 | depends on PCI | 513 | depends on PCI |
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 164e3f8d3c3d..fa1195dae425 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -93,8 +93,6 @@ extern raw_spinlock_t pci_config_lock; | |||
93 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); | 93 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); |
94 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); | 94 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); |
95 | 95 | ||
96 | extern bool mp_should_keep_irq(struct device *dev); | ||
97 | |||
98 | struct pci_raw_ops { | 96 | struct pci_raw_ops { |
99 | int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, | 97 | int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, |
100 | int reg, int len, u32 *val); | 98 | int reg, int len, u32 *val); |
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index d979e5abae55..536240fa9a95 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h | |||
@@ -152,6 +152,10 @@ | |||
152 | #define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668 | 152 | #define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668 |
153 | #define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669 | 153 | #define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669 |
154 | 154 | ||
155 | #define MSR_CORE_PERF_LIMIT_REASONS 0x00000690 | ||
156 | #define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0 | ||
157 | #define MSR_RING_PERF_LIMIT_REASONS 0x000006B1 | ||
158 | |||
155 | /* Hardware P state interface */ | 159 | /* Hardware P state interface */ |
156 | #define MSR_PPERF 0x0000064e | 160 | #define MSR_PPERF 0x0000064e |
157 | #define MSR_PERF_LIMIT_REASONS 0x0000064f | 161 | #define MSR_PERF_LIMIT_REASONS 0x0000064f |
@@ -362,6 +366,7 @@ | |||
362 | 366 | ||
363 | #define MSR_IA32_PERF_STATUS 0x00000198 | 367 | #define MSR_IA32_PERF_STATUS 0x00000198 |
364 | #define MSR_IA32_PERF_CTL 0x00000199 | 368 | #define MSR_IA32_PERF_CTL 0x00000199 |
369 | #define INTEL_PERF_CTL_MASK 0xffff | ||
365 | #define MSR_AMD_PSTATE_DEF_BASE 0xc0010064 | 370 | #define MSR_AMD_PSTATE_DEF_BASE 0xc0010064 |
366 | #define MSR_AMD_PERF_STATUS 0xc0010063 | 371 | #define MSR_AMD_PERF_STATUS 0xc0010063 |
367 | #define MSR_AMD_PERF_CTL 0xc0010062 | 372 | #define MSR_AMD_PERF_CTL 0xc0010062 |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a18fff361c7f..ae97ed0873c6 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -845,13 +845,7 @@ int acpi_ioapic_registered(acpi_handle handle, u32 gsi_base) | |||
845 | 845 | ||
846 | static int __init acpi_parse_sbf(struct acpi_table_header *table) | 846 | static int __init acpi_parse_sbf(struct acpi_table_header *table) |
847 | { | 847 | { |
848 | struct acpi_table_boot *sb; | 848 | struct acpi_table_boot *sb = (struct acpi_table_boot *)table; |
849 | |||
850 | sb = (struct acpi_table_boot *)table; | ||
851 | if (!sb) { | ||
852 | printk(KERN_WARNING PREFIX "Unable to map SBF\n"); | ||
853 | return -ENODEV; | ||
854 | } | ||
855 | 849 | ||
856 | sbf_port = sb->cmos_index; /* Save CMOS port */ | 850 | sbf_port = sb->cmos_index; /* Save CMOS port */ |
857 | 851 | ||
@@ -865,13 +859,7 @@ static struct resource *hpet_res __initdata; | |||
865 | 859 | ||
866 | static int __init acpi_parse_hpet(struct acpi_table_header *table) | 860 | static int __init acpi_parse_hpet(struct acpi_table_header *table) |
867 | { | 861 | { |
868 | struct acpi_table_hpet *hpet_tbl; | 862 | struct acpi_table_hpet *hpet_tbl = (struct acpi_table_hpet *)table; |
869 | |||
870 | hpet_tbl = (struct acpi_table_hpet *)table; | ||
871 | if (!hpet_tbl) { | ||
872 | printk(KERN_WARNING PREFIX "Unable to map HPET\n"); | ||
873 | return -ENODEV; | ||
874 | } | ||
875 | 863 | ||
876 | if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) { | 864 | if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) { |
877 | printk(KERN_WARNING PREFIX "HPET timers must be located in " | 865 | printk(KERN_WARNING PREFIX "HPET timers must be located in " |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index cfd1b132b8e3..6ac273832f28 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -10,9 +10,6 @@ | |||
10 | struct pci_root_info { | 10 | struct pci_root_info { |
11 | struct acpi_device *bridge; | 11 | struct acpi_device *bridge; |
12 | char name[16]; | 12 | char name[16]; |
13 | unsigned int res_num; | ||
14 | struct resource *res; | ||
15 | resource_size_t *res_offset; | ||
16 | struct pci_sysdata sd; | 13 | struct pci_sysdata sd; |
17 | #ifdef CONFIG_PCI_MMCONFIG | 14 | #ifdef CONFIG_PCI_MMCONFIG |
18 | bool mcfg_added; | 15 | bool mcfg_added; |
@@ -218,130 +215,41 @@ static void teardown_mcfg_map(struct pci_root_info *info) | |||
218 | } | 215 | } |
219 | #endif | 216 | #endif |
220 | 217 | ||
221 | static acpi_status resource_to_addr(struct acpi_resource *resource, | 218 | static void validate_resources(struct device *dev, struct list_head *crs_res, |
222 | struct acpi_resource_address64 *addr) | 219 | unsigned long type) |
223 | { | ||
224 | acpi_status status; | ||
225 | struct acpi_resource_memory24 *memory24; | ||
226 | struct acpi_resource_memory32 *memory32; | ||
227 | struct acpi_resource_fixed_memory32 *fixed_memory32; | ||
228 | |||
229 | memset(addr, 0, sizeof(*addr)); | ||
230 | switch (resource->type) { | ||
231 | case ACPI_RESOURCE_TYPE_MEMORY24: | ||
232 | memory24 = &resource->data.memory24; | ||
233 | addr->resource_type = ACPI_MEMORY_RANGE; | ||
234 | addr->minimum = memory24->minimum; | ||
235 | addr->address_length = memory24->address_length; | ||
236 | addr->maximum = addr->minimum + addr->address_length - 1; | ||
237 | return AE_OK; | ||
238 | case ACPI_RESOURCE_TYPE_MEMORY32: | ||
239 | memory32 = &resource->data.memory32; | ||
240 | addr->resource_type = ACPI_MEMORY_RANGE; | ||
241 | addr->minimum = memory32->minimum; | ||
242 | addr->address_length = memory32->address_length; | ||
243 | addr->maximum = addr->minimum + addr->address_length - 1; | ||
244 | return AE_OK; | ||
245 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | ||
246 | fixed_memory32 = &resource->data.fixed_memory32; | ||
247 | addr->resource_type = ACPI_MEMORY_RANGE; | ||
248 | addr->minimum = fixed_memory32->address; | ||
249 | addr->address_length = fixed_memory32->address_length; | ||
250 | addr->maximum = addr->minimum + addr->address_length - 1; | ||
251 | return AE_OK; | ||
252 | case ACPI_RESOURCE_TYPE_ADDRESS16: | ||
253 | case ACPI_RESOURCE_TYPE_ADDRESS32: | ||
254 | case ACPI_RESOURCE_TYPE_ADDRESS64: | ||
255 | status = acpi_resource_to_address64(resource, addr); | ||
256 | if (ACPI_SUCCESS(status) && | ||
257 | (addr->resource_type == ACPI_MEMORY_RANGE || | ||
258 | addr->resource_type == ACPI_IO_RANGE) && | ||
259 | addr->address_length > 0) { | ||
260 | return AE_OK; | ||
261 | } | ||
262 | break; | ||
263 | } | ||
264 | return AE_ERROR; | ||
265 | } | ||
266 | |||
267 | static acpi_status count_resource(struct acpi_resource *acpi_res, void *data) | ||
268 | { | 220 | { |
269 | struct pci_root_info *info = data; | 221 | LIST_HEAD(list); |
270 | struct acpi_resource_address64 addr; | 222 | struct resource *res1, *res2, *root = NULL; |
271 | acpi_status status; | 223 | struct resource_entry *tmp, *entry, *entry2; |
272 | |||
273 | status = resource_to_addr(acpi_res, &addr); | ||
274 | if (ACPI_SUCCESS(status)) | ||
275 | info->res_num++; | ||
276 | return AE_OK; | ||
277 | } | ||
278 | |||
279 | static acpi_status setup_resource(struct acpi_resource *acpi_res, void *data) | ||
280 | { | ||
281 | struct pci_root_info *info = data; | ||
282 | struct resource *res; | ||
283 | struct acpi_resource_address64 addr; | ||
284 | acpi_status status; | ||
285 | unsigned long flags; | ||
286 | u64 start, orig_end, end; | ||
287 | |||
288 | status = resource_to_addr(acpi_res, &addr); | ||
289 | if (!ACPI_SUCCESS(status)) | ||
290 | return AE_OK; | ||
291 | |||
292 | if (addr.resource_type == ACPI_MEMORY_RANGE) { | ||
293 | flags = IORESOURCE_MEM; | ||
294 | if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY) | ||
295 | flags |= IORESOURCE_PREFETCH; | ||
296 | } else if (addr.resource_type == ACPI_IO_RANGE) { | ||
297 | flags = IORESOURCE_IO; | ||
298 | } else | ||
299 | return AE_OK; | ||
300 | |||
301 | start = addr.minimum + addr.translation_offset; | ||
302 | orig_end = end = addr.maximum + addr.translation_offset; | ||
303 | |||
304 | /* Exclude non-addressable range or non-addressable portion of range */ | ||
305 | end = min(end, (u64)iomem_resource.end); | ||
306 | if (end <= start) { | ||
307 | dev_info(&info->bridge->dev, | ||
308 | "host bridge window [%#llx-%#llx] " | ||
309 | "(ignored, not CPU addressable)\n", start, orig_end); | ||
310 | return AE_OK; | ||
311 | } else if (orig_end != end) { | ||
312 | dev_info(&info->bridge->dev, | ||
313 | "host bridge window [%#llx-%#llx] " | ||
314 | "([%#llx-%#llx] ignored, not CPU addressable)\n", | ||
315 | start, orig_end, end + 1, orig_end); | ||
316 | } | ||
317 | 224 | ||
318 | res = &info->res[info->res_num]; | 225 | BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0); |
319 | res->name = info->name; | 226 | root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource; |
320 | res->flags = flags; | ||
321 | res->start = start; | ||
322 | res->end = end; | ||
323 | info->res_offset[info->res_num] = addr.translation_offset; | ||
324 | info->res_num++; | ||
325 | 227 | ||
326 | if (!pci_use_crs) | 228 | list_splice_init(crs_res, &list); |
327 | dev_printk(KERN_DEBUG, &info->bridge->dev, | 229 | resource_list_for_each_entry_safe(entry, tmp, &list) { |
328 | "host bridge window %pR (ignored)\n", res); | 230 | bool free = false; |
231 | resource_size_t end; | ||
329 | 232 | ||
330 | return AE_OK; | 233 | res1 = entry->res; |
331 | } | ||
332 | |||
333 | static void coalesce_windows(struct pci_root_info *info, unsigned long type) | ||
334 | { | ||
335 | int i, j; | ||
336 | struct resource *res1, *res2; | ||
337 | |||
338 | for (i = 0; i < info->res_num; i++) { | ||
339 | res1 = &info->res[i]; | ||
340 | if (!(res1->flags & type)) | 234 | if (!(res1->flags & type)) |
341 | continue; | 235 | goto next; |
236 | |||
237 | /* Exclude non-addressable range or non-addressable portion */ | ||
238 | end = min(res1->end, root->end); | ||
239 | if (end <= res1->start) { | ||
240 | dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n", | ||
241 | res1); | ||
242 | free = true; | ||
243 | goto next; | ||
244 | } else if (res1->end != end) { | ||
245 | dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n", | ||
246 | res1, (unsigned long long)end + 1, | ||
247 | (unsigned long long)res1->end); | ||
248 | res1->end = end; | ||
249 | } | ||
342 | 250 | ||
343 | for (j = i + 1; j < info->res_num; j++) { | 251 | resource_list_for_each_entry(entry2, crs_res) { |
344 | res2 = &info->res[j]; | 252 | res2 = entry2->res; |
345 | if (!(res2->flags & type)) | 253 | if (!(res2->flags & type)) |
346 | continue; | 254 | continue; |
347 | 255 | ||
@@ -353,118 +261,92 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type) | |||
353 | if (resource_overlaps(res1, res2)) { | 261 | if (resource_overlaps(res1, res2)) { |
354 | res2->start = min(res1->start, res2->start); | 262 | res2->start = min(res1->start, res2->start); |
355 | res2->end = max(res1->end, res2->end); | 263 | res2->end = max(res1->end, res2->end); |
356 | dev_info(&info->bridge->dev, | 264 | dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n", |
357 | "host bridge window expanded to %pR; %pR ignored\n", | ||
358 | res2, res1); | 265 | res2, res1); |
359 | res1->flags = 0; | 266 | free = true; |
267 | goto next; | ||
360 | } | 268 | } |
361 | } | 269 | } |
270 | |||
271 | next: | ||
272 | resource_list_del(entry); | ||
273 | if (free) | ||
274 | resource_list_free_entry(entry); | ||
275 | else | ||
276 | resource_list_add_tail(entry, crs_res); | ||
362 | } | 277 | } |
363 | } | 278 | } |
364 | 279 | ||
365 | static void add_resources(struct pci_root_info *info, | 280 | static void add_resources(struct pci_root_info *info, |
366 | struct list_head *resources) | 281 | struct list_head *resources, |
282 | struct list_head *crs_res) | ||
367 | { | 283 | { |
368 | int i; | 284 | struct resource_entry *entry, *tmp; |
369 | struct resource *res, *root, *conflict; | 285 | struct resource *res, *conflict, *root = NULL; |
370 | |||
371 | coalesce_windows(info, IORESOURCE_MEM); | ||
372 | coalesce_windows(info, IORESOURCE_IO); | ||
373 | 286 | ||
374 | for (i = 0; i < info->res_num; i++) { | 287 | validate_resources(&info->bridge->dev, crs_res, IORESOURCE_MEM); |
375 | res = &info->res[i]; | 288 | validate_resources(&info->bridge->dev, crs_res, IORESOURCE_IO); |
376 | 289 | ||
290 | resource_list_for_each_entry_safe(entry, tmp, crs_res) { | ||
291 | res = entry->res; | ||
377 | if (res->flags & IORESOURCE_MEM) | 292 | if (res->flags & IORESOURCE_MEM) |
378 | root = &iomem_resource; | 293 | root = &iomem_resource; |
379 | else if (res->flags & IORESOURCE_IO) | 294 | else if (res->flags & IORESOURCE_IO) |
380 | root = &ioport_resource; | 295 | root = &ioport_resource; |
381 | else | 296 | else |
382 | continue; | 297 | BUG_ON(res); |
383 | 298 | ||
384 | conflict = insert_resource_conflict(root, res); | 299 | conflict = insert_resource_conflict(root, res); |
385 | if (conflict) | 300 | if (conflict) { |
386 | dev_info(&info->bridge->dev, | 301 | dev_info(&info->bridge->dev, |
387 | "ignoring host bridge window %pR (conflicts with %s %pR)\n", | 302 | "ignoring host bridge window %pR (conflicts with %s %pR)\n", |
388 | res, conflict->name, conflict); | 303 | res, conflict->name, conflict); |
389 | else | 304 | resource_list_destroy_entry(entry); |
390 | pci_add_resource_offset(resources, res, | 305 | } |
391 | info->res_offset[i]); | ||
392 | } | 306 | } |
393 | } | ||
394 | 307 | ||
395 | static void free_pci_root_info_res(struct pci_root_info *info) | 308 | list_splice_tail(crs_res, resources); |
396 | { | ||
397 | kfree(info->res); | ||
398 | info->res = NULL; | ||
399 | kfree(info->res_offset); | ||
400 | info->res_offset = NULL; | ||
401 | info->res_num = 0; | ||
402 | } | 309 | } |
403 | 310 | ||
404 | static void __release_pci_root_info(struct pci_root_info *info) | 311 | static void release_pci_root_info(struct pci_host_bridge *bridge) |
405 | { | 312 | { |
406 | int i; | ||
407 | struct resource *res; | 313 | struct resource *res; |
314 | struct resource_entry *entry; | ||
315 | struct pci_root_info *info = bridge->release_data; | ||
408 | 316 | ||
409 | for (i = 0; i < info->res_num; i++) { | 317 | resource_list_for_each_entry(entry, &bridge->windows) { |
410 | res = &info->res[i]; | 318 | res = entry->res; |
411 | 319 | if (res->parent && | |
412 | if (!res->parent) | 320 | (res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) |
413 | continue; | 321 | release_resource(res); |
414 | |||
415 | if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) | ||
416 | continue; | ||
417 | |||
418 | release_resource(res); | ||
419 | } | 322 | } |
420 | 323 | ||
421 | free_pci_root_info_res(info); | ||
422 | |||
423 | teardown_mcfg_map(info); | 324 | teardown_mcfg_map(info); |
424 | |||
425 | kfree(info); | 325 | kfree(info); |
426 | } | 326 | } |
427 | 327 | ||
428 | static void release_pci_root_info(struct pci_host_bridge *bridge) | ||
429 | { | ||
430 | struct pci_root_info *info = bridge->release_data; | ||
431 | |||
432 | __release_pci_root_info(info); | ||
433 | } | ||
434 | |||
435 | static void probe_pci_root_info(struct pci_root_info *info, | 328 | static void probe_pci_root_info(struct pci_root_info *info, |
436 | struct acpi_device *device, | 329 | struct acpi_device *device, |
437 | int busnum, int domain) | 330 | int busnum, int domain, |
331 | struct list_head *list) | ||
438 | { | 332 | { |
439 | size_t size; | 333 | int ret; |
334 | struct resource_entry *entry; | ||
440 | 335 | ||
441 | sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); | 336 | sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); |
442 | info->bridge = device; | 337 | info->bridge = device; |
443 | 338 | ret = acpi_dev_get_resources(device, list, | |
444 | info->res_num = 0; | 339 | acpi_dev_filter_resource_type_cb, |
445 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, | 340 | (void *)(IORESOURCE_IO | IORESOURCE_MEM)); |
446 | info); | 341 | if (ret < 0) |
447 | if (!info->res_num) | 342 | dev_warn(&device->dev, |
448 | return; | 343 | "failed to parse _CRS method, error code %d\n", ret); |
449 | 344 | else if (ret == 0) | |
450 | size = sizeof(*info->res) * info->res_num; | 345 | dev_dbg(&device->dev, |
451 | info->res = kzalloc_node(size, GFP_KERNEL, info->sd.node); | 346 | "no IO and memory resources present in _CRS\n"); |
452 | if (!info->res) { | 347 | else |
453 | info->res_num = 0; | 348 | resource_list_for_each_entry(entry, list) |
454 | return; | 349 | entry->res->name = info->name; |
455 | } | ||
456 | |||
457 | size = sizeof(*info->res_offset) * info->res_num; | ||
458 | info->res_num = 0; | ||
459 | info->res_offset = kzalloc_node(size, GFP_KERNEL, info->sd.node); | ||
460 | if (!info->res_offset) { | ||
461 | kfree(info->res); | ||
462 | info->res = NULL; | ||
463 | return; | ||
464 | } | ||
465 | |||
466 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, | ||
467 | info); | ||
468 | } | 350 | } |
469 | 351 | ||
470 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | 352 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) |
@@ -473,6 +355,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
473 | struct pci_root_info *info; | 355 | struct pci_root_info *info; |
474 | int domain = root->segment; | 356 | int domain = root->segment; |
475 | int busnum = root->secondary.start; | 357 | int busnum = root->secondary.start; |
358 | struct resource_entry *res_entry; | ||
359 | LIST_HEAD(crs_res); | ||
476 | LIST_HEAD(resources); | 360 | LIST_HEAD(resources); |
477 | struct pci_bus *bus; | 361 | struct pci_bus *bus; |
478 | struct pci_sysdata *sd; | 362 | struct pci_sysdata *sd; |
@@ -520,18 +404,22 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
520 | memcpy(bus->sysdata, sd, sizeof(*sd)); | 404 | memcpy(bus->sysdata, sd, sizeof(*sd)); |
521 | kfree(info); | 405 | kfree(info); |
522 | } else { | 406 | } else { |
523 | probe_pci_root_info(info, device, busnum, domain); | ||
524 | |||
525 | /* insert busn res at first */ | 407 | /* insert busn res at first */ |
526 | pci_add_resource(&resources, &root->secondary); | 408 | pci_add_resource(&resources, &root->secondary); |
409 | |||
527 | /* | 410 | /* |
528 | * _CRS with no apertures is normal, so only fall back to | 411 | * _CRS with no apertures is normal, so only fall back to |
529 | * defaults or native bridge info if we're ignoring _CRS. | 412 | * defaults or native bridge info if we're ignoring _CRS. |
530 | */ | 413 | */ |
531 | if (pci_use_crs) | 414 | probe_pci_root_info(info, device, busnum, domain, &crs_res); |
532 | add_resources(info, &resources); | 415 | if (pci_use_crs) { |
533 | else { | 416 | add_resources(info, &resources, &crs_res); |
534 | free_pci_root_info_res(info); | 417 | } else { |
418 | resource_list_for_each_entry(res_entry, &crs_res) | ||
419 | dev_printk(KERN_DEBUG, &device->dev, | ||
420 | "host bridge window %pR (ignored)\n", | ||
421 | res_entry->res); | ||
422 | resource_list_free(&crs_res); | ||
535 | x86_pci_root_bus_resources(busnum, &resources); | 423 | x86_pci_root_bus_resources(busnum, &resources); |
536 | } | 424 | } |
537 | 425 | ||
@@ -546,8 +434,9 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
546 | to_pci_host_bridge(bus->bridge), | 434 | to_pci_host_bridge(bus->bridge), |
547 | release_pci_root_info, info); | 435 | release_pci_root_info, info); |
548 | } else { | 436 | } else { |
549 | pci_free_resource_list(&resources); | 437 | resource_list_free(&resources); |
550 | __release_pci_root_info(info); | 438 | teardown_mcfg_map(info); |
439 | kfree(info); | ||
551 | } | 440 | } |
552 | } | 441 | } |
553 | 442 | ||
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c index f3a2cfc14125..7bcf06a7cd12 100644 --- a/arch/x86/pci/bus_numa.c +++ b/arch/x86/pci/bus_numa.c | |||
@@ -31,7 +31,7 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) | |||
31 | { | 31 | { |
32 | struct pci_root_info *info = x86_find_pci_root_info(bus); | 32 | struct pci_root_info *info = x86_find_pci_root_info(bus); |
33 | struct pci_root_res *root_res; | 33 | struct pci_root_res *root_res; |
34 | struct pci_host_bridge_window *window; | 34 | struct resource_entry *window; |
35 | bool found = false; | 35 | bool found = false; |
36 | 36 | ||
37 | if (!info) | 37 | if (!info) |
@@ -41,7 +41,7 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources) | |||
41 | bus); | 41 | bus); |
42 | 42 | ||
43 | /* already added by acpi ? */ | 43 | /* already added by acpi ? */ |
44 | list_for_each_entry(window, resources, list) | 44 | resource_list_for_each_entry(window, resources) |
45 | if (window->res->flags & IORESOURCE_BUS) { | 45 | if (window->res->flags & IORESOURCE_BUS) { |
46 | found = true; | 46 | found = true; |
47 | break; | 47 | break; |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 2fb384724ebb..3d2612b68694 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -513,6 +513,31 @@ void __init pcibios_set_cache_line_size(void) | |||
513 | } | 513 | } |
514 | } | 514 | } |
515 | 515 | ||
516 | /* | ||
517 | * Some device drivers assume dev->irq won't change after calling | ||
518 | * pci_disable_device(). So delay releasing of IRQ resource to driver | ||
519 | * unbinding time. Otherwise it will break PM subsystem and drivers | ||
520 | * like xen-pciback etc. | ||
521 | */ | ||
522 | static int pci_irq_notifier(struct notifier_block *nb, unsigned long action, | ||
523 | void *data) | ||
524 | { | ||
525 | struct pci_dev *dev = to_pci_dev(data); | ||
526 | |||
527 | if (action != BUS_NOTIFY_UNBOUND_DRIVER) | ||
528 | return NOTIFY_DONE; | ||
529 | |||
530 | if (pcibios_disable_irq) | ||
531 | pcibios_disable_irq(dev); | ||
532 | |||
533 | return NOTIFY_OK; | ||
534 | } | ||
535 | |||
536 | static struct notifier_block pci_irq_nb = { | ||
537 | .notifier_call = pci_irq_notifier, | ||
538 | .priority = INT_MIN, | ||
539 | }; | ||
540 | |||
516 | int __init pcibios_init(void) | 541 | int __init pcibios_init(void) |
517 | { | 542 | { |
518 | if (!raw_pci_ops) { | 543 | if (!raw_pci_ops) { |
@@ -525,6 +550,9 @@ int __init pcibios_init(void) | |||
525 | 550 | ||
526 | if (pci_bf_sort >= pci_force_bf) | 551 | if (pci_bf_sort >= pci_force_bf) |
527 | pci_sort_breadthfirst(); | 552 | pci_sort_breadthfirst(); |
553 | |||
554 | bus_register_notifier(&pci_bus_type, &pci_irq_nb); | ||
555 | |||
528 | return 0; | 556 | return 0; |
529 | } | 557 | } |
530 | 558 | ||
@@ -683,12 +711,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
683 | return 0; | 711 | return 0; |
684 | } | 712 | } |
685 | 713 | ||
686 | void pcibios_disable_device (struct pci_dev *dev) | ||
687 | { | ||
688 | if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) | ||
689 | pcibios_disable_irq(dev); | ||
690 | } | ||
691 | |||
692 | int pci_ext_cfg_avail(void) | 714 | int pci_ext_cfg_avail(void) |
693 | { | 715 | { |
694 | if (raw_pci_ext_ops) | 716 | if (raw_pci_ext_ops) |
diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c index 852aa4c92da0..efb849323c74 100644 --- a/arch/x86/pci/intel_mid_pci.c +++ b/arch/x86/pci/intel_mid_pci.c | |||
@@ -234,10 +234,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) | |||
234 | 234 | ||
235 | static void intel_mid_pci_irq_disable(struct pci_dev *dev) | 235 | static void intel_mid_pci_irq_disable(struct pci_dev *dev) |
236 | { | 236 | { |
237 | if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed && | 237 | if (dev->irq_managed && dev->irq > 0) { |
238 | dev->irq > 0) { | ||
239 | mp_unmap_irq(dev->irq); | 238 | mp_unmap_irq(dev->irq); |
240 | dev->irq_managed = 0; | 239 | dev->irq_managed = 0; |
240 | dev->irq = 0; | ||
241 | } | 241 | } |
242 | } | 242 | } |
243 | 243 | ||
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 5dc6ca5e1741..e71b3dbd87b8 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -1256,22 +1256,9 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1256 | return 0; | 1256 | return 0; |
1257 | } | 1257 | } |
1258 | 1258 | ||
1259 | bool mp_should_keep_irq(struct device *dev) | ||
1260 | { | ||
1261 | if (dev->power.is_prepared) | ||
1262 | return true; | ||
1263 | #ifdef CONFIG_PM | ||
1264 | if (dev->power.runtime_status == RPM_SUSPENDING) | ||
1265 | return true; | ||
1266 | #endif | ||
1267 | |||
1268 | return false; | ||
1269 | } | ||
1270 | |||
1271 | static void pirq_disable_irq(struct pci_dev *dev) | 1259 | static void pirq_disable_irq(struct pci_dev *dev) |
1272 | { | 1260 | { |
1273 | if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) && | 1261 | if (io_apic_assign_pci_irqs && dev->irq_managed && dev->irq) { |
1274 | dev->irq_managed && dev->irq) { | ||
1275 | mp_unmap_irq(dev->irq); | 1262 | mp_unmap_irq(dev->irq); |
1276 | dev->irq = 0; | 1263 | dev->irq = 0; |
1277 | dev->irq_managed = 0; | 1264 | dev->irq_managed = 0; |
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 676e5e04e4d4..dd30b7e08bc2 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -397,12 +397,12 @@ static acpi_status check_mcfg_resource(struct acpi_resource *res, void *data) | |||
397 | 397 | ||
398 | status = acpi_resource_to_address64(res, &address); | 398 | status = acpi_resource_to_address64(res, &address); |
399 | if (ACPI_FAILURE(status) || | 399 | if (ACPI_FAILURE(status) || |
400 | (address.address_length <= 0) || | 400 | (address.address.address_length <= 0) || |
401 | (address.resource_type != ACPI_MEMORY_RANGE)) | 401 | (address.resource_type != ACPI_MEMORY_RANGE)) |
402 | return AE_OK; | 402 | return AE_OK; |
403 | 403 | ||
404 | if ((mcfg_res->start >= address.minimum) && | 404 | if ((mcfg_res->start >= address.address.minimum) && |
405 | (mcfg_res->end < (address.minimum + address.address_length))) { | 405 | (mcfg_res->end < (address.address.minimum + address.address.address_length))) { |
406 | mcfg_res->flags = 1; | 406 | mcfg_res->flags = 1; |
407 | return AE_CTRL_TERMINATE; | 407 | return AE_CTRL_TERMINATE; |
408 | } | 408 | } |