PM / sleep: Mechanism for aborting system suspends unconditionally

It sometimes may be necessary to abort a system suspend in
progress or wake up the system from suspend-to-idle even if the
pm_wakeup_event()/pm_stay_awake() mechanism is not enabled.

For this purpose, introduce a new global variable abort_suspend and
make pm_wakeup_pending() check its value.  Also add routines for
manipulating that variable.

This is going to be used in subsequent changes.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Peter Zijlstra <peterz@infradead.org>
irq / PM: Fix IRQF_NO_SUSPEND problem with shared interrupts

Since __disable_irq() only checks IRQF_NO_SUSPEND for the first
irqaction in a given irq_desc, that value of that bit for the
first irqaction affects all of the other irqactions sharing the
interrupt with it.  This is problematic in two cases.

First, if IRQF_NO_SUSPEND is set in the first irqaction and unset
in at least one of the other irqactions sharing the same interrupt,
the interrupt handlers in the other irqactions with IRQF_NO_SUSPEND
unset will be invoked after suspend_device_irqs() has returned even
though they are not supposed to.  That shouldn't be a problem if
those interrupt handlers are implemented correctly and the
corresponding devices are properly suspended, but it may lead to
functional issues otherwise.

Second, if IRQF_NO_SUSPEND is unset in the first irqaction and set
in at least one of the other irqactions sharing the same interrupt,
the interrupt handlers in the other irqactions with IRQF_NO_SUSPEND
set will not be invoked after suspend_device_irqs() has returned, but
they are supposed to be invoked then.  That may be a problem if the
corresponding devices are wakeup devices or if their interrupts have
to be properly handled during system suspend/resume too for other
reasons, which is the case for timer interrupts or the ACPI SCI for
example.

To address this, introduce a wrapper interrupt handler for shared
interrupts, irq_shared_wrapper_handler(), and make __setup_irq()
use it for shared interrupts by default.  That wrapper handler
simply invokes the original handler supplied while requesting the
IRQ if the (new) irqs_suspended global variable is unset.  Otherwise
it returns IRQ_NONE.  The wrapper handler is used for all irqactions
sharing IRQs except for irqactions with IRQF_NO_SUSPEND set that
retain their original handlers.

The irqs_suspended variable is set by suspend_device_irqs() and
unset by resume_device_irqs().  It is checked by note_interrupt()
(now called unconditionally) and if set, any unhandled interrupt
will cause the system to wake up (or system suspend in progress
to be aborted).

The additional (new) skip_suspend field in struct irq_desc is
used to track if any irqactions in the given desc have
IRQF_NO_SUSPEND set.  It is used by suspend_device_irqs() to
decide which IRQs to disable during system suspends.  This way,
all IRQs with at least one irqaction having IRQF_NO_SUSPEND set
(skip_suspend greater than 0) will stay enabled after
suspend_device_irqs(), but if any irqactions belonging to them
have IRQF_NO_SUSPEND unset, they will use the wrapper handler
that will return IRQ_NONE for them (causing system suspend to
be aborted or system wakeup from suspend-to-idle to happen).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Peter Zijlstra <peterz@infradead.org>
irq / PM: Make wakeup interrupts wake up from suspend-to-idle

Make IRQs enabled for system wakeup via enable_irq_wake() wake up
the system from suspend-to-idle.

For this purpose, introduce a new routine for enabling or disabling
wakeup interrupts, set_wakeup_irqs(), and make freeze_enter() call
it to enable them before starting the suspend-to-idle loop and to
disable them after the loop has been terminated.

Also make note_interrupt() check the wakeup status of the IRQ when
irqs_suspended is set and wake up the system (or abort system
suspend in progress) for wakeup interrupts as well as for unhandled
ones.  This is necessary to handle wakeup IRQs that aren't shared,
because their handlers may still return IRQ_HANDLED when
irqs_suspended is set.

Thus callers of enable_irq_wake() still need to be prepared for
handling interrupts from the given IRQ during the entire system
suspend and resume, but it is not guaranteed that those handlers
will be invoked every time between suspend_device_irqs() and
resume_device_irqs() (the core may simply wake up the system or
abort system suspend in progress without invoking original
interrupt handlers for the IRQ).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Peter Zijlstra <peterz@infradead.org>
x86 / PM: Set IRQCHIP_SKIP_SET_WAKE for IOAPIC IRQ chip objects

Set the IRQCHIP_SKIP_SET_WAKE for IOAPIC IRQ chip objects so that
interrupts from them can work as wakeup interrupts for suspend-to-idle.

After this change, running enable_irq_wake() on one of the IRQs in
question will succeed and IRQD_WAKEUP_STATE will be set for it, so
all of the suspend-to-idle wakeup mechanics introduced previously
will work for it automatically.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Peter Zijlstra <peterz@infradead.org>
PCI / PM: Make PCIe PME interrupts wake up from suspend-to-idle

To make PCIe PME interrupts wake up the system from suspend to idle,
make the PME driver use enable_irq_wake() on the IRQ during system
suspend (if there are any wakeup devices below the given PCIe port)
without disabling PME interrupts.  This way, an interrupt will still
trigger if a wakeup event happens and the system will be woken up (or
system suspend in progress will be aborted) by means of the new
mechanics introduced previously.

This change allows Wake-on-LAN to be used for wakeup from
suspend-to-idle on my MSI Wind tesbed netbook.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Peter Zijlstra <peterz@infradead.org>
Merge branch 'irq-pm' into bleeding-edge

* irq-pm:
  PCI / PM: Make PCIe PME interrupts wake up from suspend-to-idle
  x86 / PM: Set IRQCHIP_SKIP_SET_WAKE for IOAPIC IRQ chip objects
  irq / PM: Make wakeup interrupts wake up from suspend-to-idle
  irq / PM: Fix IRQF_NO_SUSPEND problem with shared interrupts
  PM / sleep: Mechanism for aborting system suspends unconditionally

Conflicts:
	kernel/power/suspend.c