diff options
| -rw-r--r-- | drivers/acpi/ec.c | 17 | ||||
| -rw-r--r-- | drivers/acpi/pci_irq.c | 98 | ||||
| -rw-r--r-- | drivers/acpi/processor_core.c | 16 | ||||
| -rw-r--r-- | drivers/acpi/utilities/utobject.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/video.c | 2 | ||||
| -rw-r--r-- | kernel/power/snapshot.c | 41 |
6 files changed, 155 insertions, 21 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index caf873c14bfb..e7e197e3a4ff 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -129,6 +129,7 @@ static struct acpi_ec { | |||
| 129 | struct mutex lock; | 129 | struct mutex lock; |
| 130 | wait_queue_head_t wait; | 130 | wait_queue_head_t wait; |
| 131 | struct list_head list; | 131 | struct list_head list; |
| 132 | atomic_t irq_count; | ||
| 132 | u8 handlers_installed; | 133 | u8 handlers_installed; |
| 133 | } *boot_ec, *first_ec; | 134 | } *boot_ec, *first_ec; |
| 134 | 135 | ||
| @@ -181,6 +182,8 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) | |||
| 181 | { | 182 | { |
| 182 | int ret = 0; | 183 | int ret = 0; |
| 183 | 184 | ||
| 185 | atomic_set(&ec->irq_count, 0); | ||
| 186 | |||
| 184 | if (unlikely(event == ACPI_EC_EVENT_OBF_1 && | 187 | if (unlikely(event == ACPI_EC_EVENT_OBF_1 && |
| 185 | test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags))) | 188 | test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags))) |
| 186 | force_poll = 1; | 189 | force_poll = 1; |
| @@ -227,6 +230,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) | |||
| 227 | while (time_before(jiffies, delay)) { | 230 | while (time_before(jiffies, delay)) { |
| 228 | if (acpi_ec_check_status(ec, event)) | 231 | if (acpi_ec_check_status(ec, event)) |
| 229 | goto end; | 232 | goto end; |
| 233 | msleep(5); | ||
| 230 | } | 234 | } |
| 231 | } | 235 | } |
| 232 | pr_err(PREFIX "acpi_ec_wait timeout," | 236 | pr_err(PREFIX "acpi_ec_wait timeout," |
| @@ -529,6 +533,13 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
| 529 | struct acpi_ec *ec = data; | 533 | struct acpi_ec *ec = data; |
| 530 | 534 | ||
| 531 | pr_debug(PREFIX "~~~> interrupt\n"); | 535 | pr_debug(PREFIX "~~~> interrupt\n"); |
| 536 | atomic_inc(&ec->irq_count); | ||
| 537 | if (atomic_read(&ec->irq_count) > 5) { | ||
| 538 | pr_err(PREFIX "GPE storm detected, disabling EC GPE\n"); | ||
| 539 | acpi_disable_gpe(NULL, ec->gpe, ACPI_ISR); | ||
| 540 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
| 541 | return ACPI_INTERRUPT_HANDLED; | ||
| 542 | } | ||
| 532 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 543 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
| 533 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) | 544 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) |
| 534 | wake_up(&ec->wait); | 545 | wake_up(&ec->wait); |
| @@ -943,11 +954,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
| 943 | boot_ec->command_addr = ecdt_ptr->control.address; | 954 | boot_ec->command_addr = ecdt_ptr->control.address; |
| 944 | boot_ec->data_addr = ecdt_ptr->data.address; | 955 | boot_ec->data_addr = ecdt_ptr->data.address; |
| 945 | boot_ec->gpe = ecdt_ptr->gpe; | 956 | boot_ec->gpe = ecdt_ptr->gpe; |
| 946 | if (ACPI_FAILURE(acpi_get_handle(NULL, ecdt_ptr->id, | 957 | boot_ec->handle = ACPI_ROOT_OBJECT; |
| 947 | &boot_ec->handle))) { | ||
| 948 | pr_info("Failed to locate handle for boot EC\n"); | ||
| 949 | boot_ec->handle = ACPI_ROOT_OBJECT; | ||
| 950 | } | ||
| 951 | } else { | 958 | } else { |
| 952 | /* This workaround is needed only on some broken machines, | 959 | /* This workaround is needed only on some broken machines, |
| 953 | * which require early EC, but fail to provide ECDT */ | 960 | * which require early EC, but fail to provide ECDT */ |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 7f19859580c7..7af414a3c63e 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | #include <linux/dmi.h> | ||
| 28 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
| 29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
| @@ -76,6 +77,101 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment, | |||
| 76 | return NULL; | 77 | return NULL; |
| 77 | } | 78 | } |
| 78 | 79 | ||
| 80 | /* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ | ||
| 81 | static struct dmi_system_id medion_md9580[] = { | ||
| 82 | { | ||
| 83 | .ident = "Medion MD9580-F laptop", | ||
| 84 | .matches = { | ||
| 85 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), | ||
| 86 | DMI_MATCH(DMI_PRODUCT_NAME, "A555"), | ||
| 87 | }, | ||
| 88 | }, | ||
| 89 | { } | ||
| 90 | }; | ||
| 91 | |||
| 92 | /* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */ | ||
| 93 | static struct dmi_system_id dell_optiplex[] = { | ||
| 94 | { | ||
| 95 | .ident = "Dell Optiplex GX1", | ||
| 96 | .matches = { | ||
| 97 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), | ||
| 98 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX1 600S+"), | ||
| 99 | }, | ||
| 100 | }, | ||
| 101 | { } | ||
| 102 | }; | ||
| 103 | |||
| 104 | /* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */ | ||
| 105 | static struct dmi_system_id hp_t5710[] = { | ||
| 106 | { | ||
| 107 | .ident = "HP t5710", | ||
| 108 | .matches = { | ||
| 109 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
| 110 | DMI_MATCH(DMI_PRODUCT_NAME, "hp t5000 series"), | ||
| 111 | DMI_MATCH(DMI_BOARD_NAME, "098Ch"), | ||
| 112 | }, | ||
| 113 | }, | ||
| 114 | { } | ||
| 115 | }; | ||
| 116 | |||
| 117 | struct prt_quirk { | ||
| 118 | struct dmi_system_id *system; | ||
| 119 | unsigned int segment; | ||
| 120 | unsigned int bus; | ||
| 121 | unsigned int device; | ||
| 122 | unsigned char pin; | ||
| 123 | char *source; /* according to BIOS */ | ||
| 124 | char *actual_source; | ||
| 125 | }; | ||
| 126 | |||
| 127 | /* | ||
| 128 | * These systems have incorrect _PRT entries. The BIOS claims the PCI | ||
| 129 | * interrupt at the listed segment/bus/device/pin is connected to the first | ||
| 130 | * link device, but it is actually connected to the second. | ||
| 131 | */ | ||
| 132 | static struct prt_quirk prt_quirks[] = { | ||
| 133 | { medion_md9580, 0, 0, 9, 'A', | ||
| 134 | "\\_SB_.PCI0.ISA.LNKA", | ||
| 135 | "\\_SB_.PCI0.ISA.LNKB"}, | ||
| 136 | { dell_optiplex, 0, 0, 0xd, 'A', | ||
| 137 | "\\_SB_.LNKB", | ||
| 138 | "\\_SB_.LNKA"}, | ||
| 139 | { hp_t5710, 0, 0, 1, 'A', | ||
| 140 | "\\_SB_.PCI0.LNK1", | ||
| 141 | "\\_SB_.PCI0.LNK3"}, | ||
| 142 | }; | ||
| 143 | |||
| 144 | static void | ||
| 145 | do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt) | ||
| 146 | { | ||
| 147 | int i; | ||
| 148 | struct prt_quirk *quirk; | ||
| 149 | |||
| 150 | for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) { | ||
| 151 | quirk = &prt_quirks[i]; | ||
| 152 | |||
| 153 | /* All current quirks involve link devices, not GSIs */ | ||
| 154 | if (!prt->source) | ||
| 155 | continue; | ||
| 156 | |||
| 157 | if (dmi_check_system(quirk->system) && | ||
| 158 | entry->id.segment == quirk->segment && | ||
| 159 | entry->id.bus == quirk->bus && | ||
| 160 | entry->id.device == quirk->device && | ||
| 161 | entry->pin + 'A' == quirk->pin && | ||
| 162 | !strcmp(prt->source, quirk->source) && | ||
| 163 | strlen(prt->source) >= strlen(quirk->actual_source)) { | ||
| 164 | printk(KERN_WARNING PREFIX "firmware reports " | ||
| 165 | "%04x:%02x:%02x[%c] connected to %s; " | ||
| 166 | "changing to %s\n", | ||
| 167 | entry->id.segment, entry->id.bus, | ||
| 168 | entry->id.device, 'A' + entry->pin, | ||
| 169 | prt->source, quirk->actual_source); | ||
| 170 | strcpy(prt->source, quirk->actual_source); | ||
| 171 | } | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 79 | static int | 175 | static int |
| 80 | acpi_pci_irq_add_entry(acpi_handle handle, | 176 | acpi_pci_irq_add_entry(acpi_handle handle, |
| 81 | int segment, int bus, struct acpi_pci_routing_table *prt) | 177 | int segment, int bus, struct acpi_pci_routing_table *prt) |
| @@ -96,6 +192,8 @@ acpi_pci_irq_add_entry(acpi_handle handle, | |||
| 96 | entry->id.function = prt->address & 0xFFFF; | 192 | entry->id.function = prt->address & 0xFFFF; |
| 97 | entry->pin = prt->pin; | 193 | entry->pin = prt->pin; |
| 98 | 194 | ||
| 195 | do_prt_fixups(entry, prt); | ||
| 196 | |||
| 99 | /* | 197 | /* |
| 100 | * Type 1: Dynamic | 198 | * Type 1: Dynamic |
| 101 | * --------------- | 199 | * --------------- |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index a3cc8a98255c..d9316ab66347 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
| @@ -840,17 +840,19 @@ static int is_processor_present(acpi_handle handle) | |||
| 840 | 840 | ||
| 841 | 841 | ||
| 842 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | 842 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); |
| 843 | /* | ||
| 844 | * if a processor object does not have an _STA object, | ||
| 845 | * OSPM assumes that the processor is present. | ||
| 846 | */ | ||
| 847 | if (status == AE_NOT_FOUND) | ||
| 848 | return 1; | ||
| 849 | 843 | ||
| 850 | if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT)) | 844 | if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT)) |
| 851 | return 1; | 845 | return 1; |
| 852 | 846 | ||
| 853 | ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present")); | 847 | /* |
| 848 | * _STA is mandatory for a processor that supports hot plug | ||
| 849 | */ | ||
| 850 | if (status == AE_NOT_FOUND) | ||
| 851 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| 852 | "Processor does not support hot plug\n")); | ||
| 853 | else | ||
| 854 | ACPI_EXCEPTION((AE_INFO, status, | ||
| 855 | "Processor Device is not present")); | ||
| 854 | return 0; | 856 | return 0; |
| 855 | } | 857 | } |
| 856 | 858 | ||
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index 76ee766c84f9..e08b3fa6639f 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c | |||
| @@ -432,7 +432,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, | |||
| 432 | * element -- which is legal) | 432 | * element -- which is legal) |
| 433 | */ | 433 | */ |
| 434 | if (!internal_object) { | 434 | if (!internal_object) { |
| 435 | *obj_length = 0; | 435 | *obj_length = sizeof(union acpi_object); |
| 436 | return_ACPI_STATUS(AE_OK); | 436 | return_ACPI_STATUS(AE_OK); |
| 437 | } | 437 | } |
| 438 | 438 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 12cce69b5441..ace958cb3894 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -713,7 +713,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
| 713 | 713 | ||
| 714 | kfree(obj); | 714 | kfree(obj); |
| 715 | 715 | ||
| 716 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ | 716 | if (device->cap._BCL && device->cap._BCM && max_level > 0) { |
| 717 | int result; | 717 | int result; |
| 718 | static int count = 0; | 718 | static int count = 0; |
| 719 | char *name; | 719 | char *name; |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 72a020cabb4c..5f91a07c4eac 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
| @@ -447,7 +447,7 @@ static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free) | |||
| 447 | * of @bm->cur_zone_bm are updated. | 447 | * of @bm->cur_zone_bm are updated. |
| 448 | */ | 448 | */ |
| 449 | 449 | ||
| 450 | static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn, | 450 | static int memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn, |
| 451 | void **addr, unsigned int *bit_nr) | 451 | void **addr, unsigned int *bit_nr) |
| 452 | { | 452 | { |
| 453 | struct zone_bitmap *zone_bm; | 453 | struct zone_bitmap *zone_bm; |
| @@ -461,7 +461,8 @@ static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn, | |||
| 461 | while (pfn < zone_bm->start_pfn || pfn >= zone_bm->end_pfn) { | 461 | while (pfn < zone_bm->start_pfn || pfn >= zone_bm->end_pfn) { |
| 462 | zone_bm = zone_bm->next; | 462 | zone_bm = zone_bm->next; |
| 463 | 463 | ||
| 464 | BUG_ON(!zone_bm); | 464 | if (!zone_bm) |
| 465 | return -EFAULT; | ||
| 465 | } | 466 | } |
| 466 | bm->cur.zone_bm = zone_bm; | 467 | bm->cur.zone_bm = zone_bm; |
| 467 | } | 468 | } |
| @@ -479,23 +480,40 @@ static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn, | |||
| 479 | pfn -= bb->start_pfn; | 480 | pfn -= bb->start_pfn; |
| 480 | *bit_nr = pfn % BM_BITS_PER_CHUNK; | 481 | *bit_nr = pfn % BM_BITS_PER_CHUNK; |
| 481 | *addr = bb->data + pfn / BM_BITS_PER_CHUNK; | 482 | *addr = bb->data + pfn / BM_BITS_PER_CHUNK; |
| 483 | return 0; | ||
| 482 | } | 484 | } |
| 483 | 485 | ||
| 484 | static void memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn) | 486 | static void memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn) |
| 485 | { | 487 | { |
| 486 | void *addr; | 488 | void *addr; |
| 487 | unsigned int bit; | 489 | unsigned int bit; |
| 490 | int error; | ||
| 488 | 491 | ||
| 489 | memory_bm_find_bit(bm, pfn, &addr, &bit); | 492 | error = memory_bm_find_bit(bm, pfn, &addr, &bit); |
| 493 | BUG_ON(error); | ||
| 490 | set_bit(bit, addr); | 494 | set_bit(bit, addr); |
| 491 | } | 495 | } |
| 492 | 496 | ||
| 497 | static int mem_bm_set_bit_check(struct memory_bitmap *bm, unsigned long pfn) | ||
| 498 | { | ||
| 499 | void *addr; | ||
| 500 | unsigned int bit; | ||
| 501 | int error; | ||
| 502 | |||
| 503 | error = memory_bm_find_bit(bm, pfn, &addr, &bit); | ||
| 504 | if (!error) | ||
| 505 | set_bit(bit, addr); | ||
| 506 | return error; | ||
| 507 | } | ||
| 508 | |||
| 493 | static void memory_bm_clear_bit(struct memory_bitmap *bm, unsigned long pfn) | 509 | static void memory_bm_clear_bit(struct memory_bitmap *bm, unsigned long pfn) |
| 494 | { | 510 | { |
| 495 | void *addr; | 511 | void *addr; |
| 496 | unsigned int bit; | 512 | unsigned int bit; |
| 513 | int error; | ||
| 497 | 514 | ||
| 498 | memory_bm_find_bit(bm, pfn, &addr, &bit); | 515 | error = memory_bm_find_bit(bm, pfn, &addr, &bit); |
| 516 | BUG_ON(error); | ||
| 499 | clear_bit(bit, addr); | 517 | clear_bit(bit, addr); |
| 500 | } | 518 | } |
| 501 | 519 | ||
| @@ -503,8 +521,10 @@ static int memory_bm_test_bit(struct memory_bitmap *bm, unsigned long pfn) | |||
| 503 | { | 521 | { |
| 504 | void *addr; | 522 | void *addr; |
| 505 | unsigned int bit; | 523 | unsigned int bit; |
| 524 | int error; | ||
| 506 | 525 | ||
| 507 | memory_bm_find_bit(bm, pfn, &addr, &bit); | 526 | error = memory_bm_find_bit(bm, pfn, &addr, &bit); |
| 527 | BUG_ON(error); | ||
| 508 | return test_bit(bit, addr); | 528 | return test_bit(bit, addr); |
| 509 | } | 529 | } |
| 510 | 530 | ||
| @@ -709,8 +729,15 @@ static void mark_nosave_pages(struct memory_bitmap *bm) | |||
| 709 | region->end_pfn << PAGE_SHIFT); | 729 | region->end_pfn << PAGE_SHIFT); |
| 710 | 730 | ||
| 711 | for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++) | 731 | for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++) |
| 712 | if (pfn_valid(pfn)) | 732 | if (pfn_valid(pfn)) { |
| 713 | memory_bm_set_bit(bm, pfn); | 733 | /* |
| 734 | * It is safe to ignore the result of | ||
| 735 | * mem_bm_set_bit_check() here, since we won't | ||
| 736 | * touch the PFNs for which the error is | ||
| 737 | * returned anyway. | ||
| 738 | */ | ||
| 739 | mem_bm_set_bit_check(bm, pfn); | ||
| 740 | } | ||
| 714 | } | 741 | } |
| 715 | } | 742 | } |
| 716 | 743 | ||
