Commit 362b06bb authored by David Shaohua Li's avatar David Shaohua Li Committed by Len Brown
Browse files

[ACPI] S3 Suspend to RAM: interrupt resume fix

Delete PCI Interrupt Link Device .resume method --
it is the device driver's job to request interrupts,
not the Link's job to remember what the devices want.

This addresses the issue of attempting to run
the ACPI interpreter too early in resume, when
interrupts are still disabled.

http://bugzilla.kernel.org/show_bug.cgi?id=3469



Signed-off-by: default avatarDavid Shaohua Li <shaohua.li@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 5ae947ec
Loading
Loading
Loading
Loading
+14 −22
Original line number Original line Diff line number Diff line
@@ -72,10 +72,12 @@ struct acpi_pci_link_irq {
	u8			active;			/* Current IRQ */
	u8			active;			/* Current IRQ */
	u8			edge_level;		/* All IRQs */
	u8			edge_level;		/* All IRQs */
	u8			active_high_low;	/* All IRQs */
	u8			active_high_low;	/* All IRQs */
	u8			initialized;
	u8			resource_type;
	u8			resource_type;
	u8			possible_count;
	u8			possible_count;
	u8			possible[ACPI_PCI_LINK_MAX_POSSIBLE];
	u8			possible[ACPI_PCI_LINK_MAX_POSSIBLE];
	u8			initialized:1;
	u8			suspend_resume:1;
	u8			reserved:6;
};
};


struct acpi_pci_link {
struct acpi_pci_link {
@@ -530,6 +532,10 @@ static int acpi_pci_link_allocate(


	ACPI_FUNCTION_TRACE("acpi_pci_link_allocate");
	ACPI_FUNCTION_TRACE("acpi_pci_link_allocate");


	if (link->irq.suspend_resume) {
		acpi_pci_link_set(link, link->irq.active);
		link->irq.suspend_resume = 0;
	}
	if (link->irq.initialized)
	if (link->irq.initialized)
		return_VALUE(0);
		return_VALUE(0);


@@ -713,38 +719,24 @@ end:
	return_VALUE(result);
	return_VALUE(result);
}
}



static int
static int
acpi_pci_link_resume (
irqrouter_suspend(
	struct acpi_pci_link	*link)
	struct sys_device *dev,
{
	u32	state)
	ACPI_FUNCTION_TRACE("acpi_pci_link_resume");
	
	if (link->irq.active && link->irq.initialized)
		return_VALUE(acpi_pci_link_set(link, link->irq.active));
	else
		return_VALUE(0);
}


static int
irqrouter_resume(
	struct sys_device *dev)
{
{
	struct list_head        *node = NULL;
	struct list_head        *node = NULL;
	struct acpi_pci_link    *link = NULL;
	struct acpi_pci_link    *link = NULL;


	ACPI_FUNCTION_TRACE("irqrouter_resume");
	ACPI_FUNCTION_TRACE("irqrouter_suspend");


	list_for_each(node, &acpi_link.entries) {
	list_for_each(node, &acpi_link.entries) {

		link = list_entry(node, struct acpi_pci_link, node);
		link = list_entry(node, struct acpi_pci_link, node);
		if (!link) {
		if (!link) {
			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
			continue;
			continue;
		}
		}

		if (link->irq.active && link->irq.initialized)
		acpi_pci_link_resume(link);
			link->irq.suspend_resume = 1;
	}
	}
	return_VALUE(0);
	return_VALUE(0);
}
}
@@ -856,7 +848,7 @@ __setup("acpi_irq_balance", acpi_irq_balance_set);


static struct sysdev_class irqrouter_sysdev_class = {
static struct sysdev_class irqrouter_sysdev_class = {
        set_kset_name("irqrouter"),
        set_kset_name("irqrouter"),
        .resume = irqrouter_resume,
        .suspend = irqrouter_suspend,
};
};