Merge branches 'release', 'bugzilla-8570', 'bugzilla-9966', 'bugzilla-9998', 'bugzilla-10100', 'bugzilla-10132', 'bugzilla-10138' and 'bugzilla-10206' into release
This commit is contained in:
commit
1ca721cdb7
@ -129,6 +129,7 @@ static struct acpi_ec {
|
||||
struct mutex lock;
|
||||
wait_queue_head_t wait;
|
||||
struct list_head list;
|
||||
atomic_t irq_count;
|
||||
u8 handlers_installed;
|
||||
} *boot_ec, *first_ec;
|
||||
|
||||
@ -181,6 +182,8 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
atomic_set(&ec->irq_count, 0);
|
||||
|
||||
if (unlikely(event == ACPI_EC_EVENT_OBF_1 &&
|
||||
test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags)))
|
||||
force_poll = 1;
|
||||
@ -227,6 +230,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
|
||||
while (time_before(jiffies, delay)) {
|
||||
if (acpi_ec_check_status(ec, event))
|
||||
goto end;
|
||||
msleep(5);
|
||||
}
|
||||
}
|
||||
pr_err(PREFIX "acpi_ec_wait timeout,"
|
||||
@ -529,6 +533,13 @@ static u32 acpi_ec_gpe_handler(void *data)
|
||||
struct acpi_ec *ec = data;
|
||||
|
||||
pr_debug(PREFIX "~~~> interrupt\n");
|
||||
atomic_inc(&ec->irq_count);
|
||||
if (atomic_read(&ec->irq_count) > 5) {
|
||||
pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
|
||||
acpi_disable_gpe(NULL, ec->gpe, ACPI_ISR);
|
||||
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
|
||||
return ACPI_INTERRUPT_HANDLED;
|
||||
}
|
||||
clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
|
||||
if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
|
||||
wake_up(&ec->wait);
|
||||
@ -943,11 +954,7 @@ int __init acpi_ec_ecdt_probe(void)
|
||||
boot_ec->command_addr = ecdt_ptr->control.address;
|
||||
boot_ec->data_addr = ecdt_ptr->data.address;
|
||||
boot_ec->gpe = ecdt_ptr->gpe;
|
||||
if (ACPI_FAILURE(acpi_get_handle(NULL, ecdt_ptr->id,
|
||||
&boot_ec->handle))) {
|
||||
pr_info("Failed to locate handle for boot EC\n");
|
||||
boot_ec->handle = ACPI_ROOT_OBJECT;
|
||||
}
|
||||
boot_ec->handle = ACPI_ROOT_OBJECT;
|
||||
} else {
|
||||
/* This workaround is needed only on some broken machines,
|
||||
* which require early EC, but fail to provide ECDT */
|
||||
|
@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
@ -76,6 +77,101 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */
|
||||
static struct dmi_system_id medion_md9580[] = {
|
||||
{
|
||||
.ident = "Medion MD9580-F laptop",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "A555"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
/* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */
|
||||
static struct dmi_system_id dell_optiplex[] = {
|
||||
{
|
||||
.ident = "Dell Optiplex GX1",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX1 600S+"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
/* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */
|
||||
static struct dmi_system_id hp_t5710[] = {
|
||||
{
|
||||
.ident = "HP t5710",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "hp t5000 series"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "098Ch"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
struct prt_quirk {
|
||||
struct dmi_system_id *system;
|
||||
unsigned int segment;
|
||||
unsigned int bus;
|
||||
unsigned int device;
|
||||
unsigned char pin;
|
||||
char *source; /* according to BIOS */
|
||||
char *actual_source;
|
||||
};
|
||||
|
||||
/*
|
||||
* These systems have incorrect _PRT entries. The BIOS claims the PCI
|
||||
* interrupt at the listed segment/bus/device/pin is connected to the first
|
||||
* link device, but it is actually connected to the second.
|
||||
*/
|
||||
static struct prt_quirk prt_quirks[] = {
|
||||
{ medion_md9580, 0, 0, 9, 'A',
|
||||
"\\_SB_.PCI0.ISA.LNKA",
|
||||
"\\_SB_.PCI0.ISA.LNKB"},
|
||||
{ dell_optiplex, 0, 0, 0xd, 'A',
|
||||
"\\_SB_.LNKB",
|
||||
"\\_SB_.LNKA"},
|
||||
{ hp_t5710, 0, 0, 1, 'A',
|
||||
"\\_SB_.PCI0.LNK1",
|
||||
"\\_SB_.PCI0.LNK3"},
|
||||
};
|
||||
|
||||
static void
|
||||
do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt)
|
||||
{
|
||||
int i;
|
||||
struct prt_quirk *quirk;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) {
|
||||
quirk = &prt_quirks[i];
|
||||
|
||||
/* All current quirks involve link devices, not GSIs */
|
||||
if (!prt->source)
|
||||
continue;
|
||||
|
||||
if (dmi_check_system(quirk->system) &&
|
||||
entry->id.segment == quirk->segment &&
|
||||
entry->id.bus == quirk->bus &&
|
||||
entry->id.device == quirk->device &&
|
||||
entry->pin + 'A' == quirk->pin &&
|
||||
!strcmp(prt->source, quirk->source) &&
|
||||
strlen(prt->source) >= strlen(quirk->actual_source)) {
|
||||
printk(KERN_WARNING PREFIX "firmware reports "
|
||||
"%04x:%02x:%02x[%c] connected to %s; "
|
||||
"changing to %s\n",
|
||||
entry->id.segment, entry->id.bus,
|
||||
entry->id.device, 'A' + entry->pin,
|
||||
prt->source, quirk->actual_source);
|
||||
strcpy(prt->source, quirk->actual_source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_pci_irq_add_entry(acpi_handle handle,
|
||||
int segment, int bus, struct acpi_pci_routing_table *prt)
|
||||
@ -96,6 +192,8 @@ acpi_pci_irq_add_entry(acpi_handle handle,
|
||||
entry->id.function = prt->address & 0xFFFF;
|
||||
entry->pin = prt->pin;
|
||||
|
||||
do_prt_fixups(entry, prt);
|
||||
|
||||
/*
|
||||
* Type 1: Dynamic
|
||||
* ---------------
|
||||
|
@ -840,17 +840,19 @@ static int is_processor_present(acpi_handle handle)
|
||||
|
||||
|
||||
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
|
||||
/*
|
||||
* if a processor object does not have an _STA object,
|
||||
* OSPM assumes that the processor is present.
|
||||
*/
|
||||
if (status == AE_NOT_FOUND)
|
||||
return 1;
|
||||
|
||||
if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
|
||||
return 1;
|
||||
|
||||
ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present"));
|
||||
/*
|
||||
* _STA is mandatory for a processor that supports hot plug
|
||||
*/
|
||||
if (status == AE_NOT_FOUND)
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Processor does not support hot plug\n"));
|
||||
else
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Processor Device is not present"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -432,7 +432,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
|
||||
* element -- which is legal)
|
||||
*/
|
||||
if (!internal_object) {
|
||||
*obj_length = 0;
|
||||
*obj_length = sizeof(union acpi_object);
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
|
@ -713,7 +713,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
|
||||
|
||||
kfree(obj);
|
||||
|
||||
if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
|
||||
if (device->cap._BCL && device->cap._BCM && max_level > 0) {
|
||||
int result;
|
||||
static int count = 0;
|
||||
char *name;
|
||||
|
@ -447,7 +447,7 @@ static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free)
|
||||
* of @bm->cur_zone_bm are updated.
|
||||
*/
|
||||
|
||||
static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn,
|
||||
static int memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn,
|
||||
void **addr, unsigned int *bit_nr)
|
||||
{
|
||||
struct zone_bitmap *zone_bm;
|
||||
@ -461,7 +461,8 @@ static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn,
|
||||
while (pfn < zone_bm->start_pfn || pfn >= zone_bm->end_pfn) {
|
||||
zone_bm = zone_bm->next;
|
||||
|
||||
BUG_ON(!zone_bm);
|
||||
if (!zone_bm)
|
||||
return -EFAULT;
|
||||
}
|
||||
bm->cur.zone_bm = zone_bm;
|
||||
}
|
||||
@ -479,23 +480,40 @@ static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn,
|
||||
pfn -= bb->start_pfn;
|
||||
*bit_nr = pfn % BM_BITS_PER_CHUNK;
|
||||
*addr = bb->data + pfn / BM_BITS_PER_CHUNK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn)
|
||||
{
|
||||
void *addr;
|
||||
unsigned int bit;
|
||||
int error;
|
||||
|
||||
memory_bm_find_bit(bm, pfn, &addr, &bit);
|
||||
error = memory_bm_find_bit(bm, pfn, &addr, &bit);
|
||||
BUG_ON(error);
|
||||
set_bit(bit, addr);
|
||||
}
|
||||
|
||||
static int mem_bm_set_bit_check(struct memory_bitmap *bm, unsigned long pfn)
|
||||
{
|
||||
void *addr;
|
||||
unsigned int bit;
|
||||
int error;
|
||||
|
||||
error = memory_bm_find_bit(bm, pfn, &addr, &bit);
|
||||
if (!error)
|
||||
set_bit(bit, addr);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void memory_bm_clear_bit(struct memory_bitmap *bm, unsigned long pfn)
|
||||
{
|
||||
void *addr;
|
||||
unsigned int bit;
|
||||
int error;
|
||||
|
||||
memory_bm_find_bit(bm, pfn, &addr, &bit);
|
||||
error = memory_bm_find_bit(bm, pfn, &addr, &bit);
|
||||
BUG_ON(error);
|
||||
clear_bit(bit, addr);
|
||||
}
|
||||
|
||||
@ -503,8 +521,10 @@ static int memory_bm_test_bit(struct memory_bitmap *bm, unsigned long pfn)
|
||||
{
|
||||
void *addr;
|
||||
unsigned int bit;
|
||||
int error;
|
||||
|
||||
memory_bm_find_bit(bm, pfn, &addr, &bit);
|
||||
error = memory_bm_find_bit(bm, pfn, &addr, &bit);
|
||||
BUG_ON(error);
|
||||
return test_bit(bit, addr);
|
||||
}
|
||||
|
||||
@ -709,8 +729,15 @@ static void mark_nosave_pages(struct memory_bitmap *bm)
|
||||
region->end_pfn << PAGE_SHIFT);
|
||||
|
||||
for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++)
|
||||
if (pfn_valid(pfn))
|
||||
memory_bm_set_bit(bm, pfn);
|
||||
if (pfn_valid(pfn)) {
|
||||
/*
|
||||
* It is safe to ignore the result of
|
||||
* mem_bm_set_bit_check() here, since we won't
|
||||
* touch the PFNs for which the error is
|
||||
* returned anyway.
|
||||
*/
|
||||
mem_bm_set_bit_check(bm, pfn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user