Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ca721cd authored by Len Brown's avatar Len Brown
Browse files

Merge branches 'release', 'bugzilla-8570', 'bugzilla-9966', 'bugzilla-9998',...

Merge branches 'release', 'bugzilla-8570', 'bugzilla-9966', 'bugzilla-9998', 'bugzilla-10100', 'bugzilla-10132', 'bugzilla-10138' and 'bugzilla-10206' into release
Loading
+12 −5
Original line number Diff line number Diff line
@@ -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;
		}
	} else {
		/* This workaround is needed only on some broken machines,
		 * which require early EC, but fail to provide ECDT */
+98 −0
Original line number Diff line number Diff line
@@ -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
	 * ---------------
+9 −7
Original line number Diff line number Diff line
@@ -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;
}

+1 −1
Original line number Diff line number Diff line
@@ -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);
	}

+1 −1
Original line number Diff line number Diff line
@@ -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;
Loading