Merge tag 'pm+acpi-4.0-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Merge commit. Changes below are compared with the first parent: 7c5bde7a.
Changes
21 files changed · +331 −119
Only the first 600 diff lines are shown. Download the complete patch.
Documentation/power/suspend-and-interrupts.txt
View filediff --git a/Documentation/power/suspend-and-interrupts.txt b/Documentation/power/suspend-and-interrupts.txt
index 2f9c5a5..8afb29a 100644
--- a/Documentation/power/suspend-and-interrupts.txt
+++ b/Documentation/power/suspend-and-interrupts.txt
@@ -40,8 +40,10 @@ but also to IPIs and to some other special-purpose interrupts.
The IRQF_NO_SUSPEND flag is used to indicate that to the IRQ subsystem when
requesting a special-purpose interrupt. It causes suspend_device_irqs() to
-leave the corresponding IRQ enabled so as to allow the interrupt to work all
-the time as expected.
+leave the corresponding IRQ enabled so as to allow the interrupt to work as
+expected during the suspend-resume cycle, but does not guarantee that the
+interrupt will wake the system from a suspended state -- for such cases it is
+necessary to use enable_irq_wake().
Note that the IRQF_NO_SUSPEND flag affects the entire IRQ and not just one
user of it. Thus, if the IRQ is shared, all of the interrupt handlers installed
@@ -110,8 +112,9 @@ any special interrupt handling logic for it to work.
IRQF_NO_SUSPEND and enable_irq_wake()
-------------------------------------
-There are no valid reasons to use both enable_irq_wake() and the IRQF_NO_SUSPEND
-flag on the same IRQ.
+There are very few valid reasons to use both enable_irq_wake() and the
+IRQF_NO_SUSPEND flag on the same IRQ, and it is never valid to use both for the
+same device.
First of all, if the IRQ is not shared, the rules for handling IRQF_NO_SUSPEND
interrupts (interrupt handlers are invoked after suspend_device_irqs()) are
@@ -120,4 +123,13 @@ handlers are not invoked after suspend_device_irqs()).
Second, both enable_irq_wake() and IRQF_NO_SUSPEND apply to entire IRQs and not
to individual interrupt handlers, so sharing an IRQ between a system wakeup
-interrupt source and an IRQF_NO_SUSPEND interrupt source does not make sense.
+interrupt source and an IRQF_NO_SUSPEND interrupt source does not generally
+make sense.
+
+In rare cases an IRQ can be shared between a wakeup device driver and an
+IRQF_NO_SUSPEND user. In order for this to be safe, the wakeup device driver
+must be able to discern spurious IRQs from genuine wakeup events (signalling
+the latter to the core with pm_system_wakeup()), must use enable_irq_wake() to
+ensure that the IRQ will function as a wakeup source, and must request the IRQ
+with IRQF_COND_SUSPEND to tell the core that it meets these requirements. If
+these requirements are not met, it is not valid to use IRQF_COND_SUSPEND.
arch/x86/pci/acpi.c
View filediff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 6ac2738..e469598 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -331,7 +331,7 @@ static void probe_pci_root_info(struct pci_root_info *info,
struct list_head *list)
{
int ret;
- struct resource_entry *entry;
+ struct resource_entry *entry, *tmp;
sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
info->bridge = device;
@@ -345,8 +345,13 @@ static void probe_pci_root_info(struct pci_root_info *info,
dev_dbg(&device->dev,
"no IO and memory resources present in _CRS\n");
else
- resource_list_for_each_entry(entry, list)
- entry->res->name = info->name;
+ resource_list_for_each_entry_safe(entry, tmp, list) {
+ if ((entry->res->flags & IORESOURCE_WINDOW) == 0 ||
+ (entry->res->flags & IORESOURCE_DISABLED))
+ resource_list_destroy_entry(entry);
+ else
+ entry->res->name = info->name;
+ }
}
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
drivers/acpi/resource.c
View filediff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index c723668..5589a6e 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -42,8 +42,10 @@ static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
* CHECKME: len might be required to check versus a minimum
* length as well. 1 for io is fine, but for memory it does
* not make any sense at all.
+ * Note: some BIOSes report incorrect length for ACPI address space
+ * descriptor, so remove check of 'reslen == len' to avoid regression.
*/
- if (len && reslen && reslen == len && start <= end)
+ if (len && reslen && start <= end)
return true;
pr_debug("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n",
drivers/acpi/video.c
View filediff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index debd309..26eb70c 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -2110,7 +2110,8 @@ static int __init intel_opregion_present(void)
int acpi_video_register(void)
{
- int result = 0;
+ int ret;
+
if (register_count) {
/*
* if the function of acpi_video_register is already called,
@@ -2122,9 +2123,9 @@ int acpi_video_register(void)
mutex_init(&video_list_lock);
INIT_LIST_HEAD(&video_bus_head);
- result = acpi_bus_register_driver(&acpi_video_bus);
- if (result < 0)
- return -ENODEV;
+ ret = acpi_bus_register_driver(&acpi_video_bus);
+ if (ret)
+ return ret;
/*
* When the acpi_video_bus is loaded successfully, increase
@@ -2176,6 +2177,17 @@ EXPORT_SYMBOL(acpi_video_unregister_backlight);
static int __init acpi_video_init(void)
{
+ /*
+ * Let the module load even if ACPI is disabled (e.g. due to
+ * a broken BIOS) so that i915.ko can still be loaded on such
+ * old systems without an AcpiOpRegion.
+ *
+ * acpi_video_register() will report -ENODEV later as well due
+ * to acpi_disabled when i915.ko tries to register itself afterwards.
+ */
+ if (acpi_disabled)
+ return 0;
+
dmi_check_system(video_dmi_table);
if (intel_opregion_present())
drivers/base/power/domain.c
View filediff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index ba4abbe..45937f8 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -2242,7 +2242,7 @@ static void rtpm_status_str(struct seq_file *s, struct device *dev)
}
static int pm_genpd_summary_one(struct seq_file *s,
- struct generic_pm_domain *gpd)
+ struct generic_pm_domain *genpd)
{
static const char * const status_lookup[] = {
[GPD_STATE_ACTIVE] = "on",
@@ -2256,26 +2256,26 @@ static int pm_genpd_summary_one(struct seq_file *s,
struct gpd_link *link;
int ret;
- ret = mutex_lock_interruptible(&gpd->lock);
+ ret = mutex_lock_interruptible(&genpd->lock);
if (ret)
return -ERESTARTSYS;
- if (WARN_ON(gpd->status >= ARRAY_SIZE(status_lookup)))
+ if (WARN_ON(genpd->status >= ARRAY_SIZE(status_lookup)))
goto exit;
- seq_printf(s, "%-30s %-15s ", gpd->name, status_lookup[gpd->status]);
+ seq_printf(s, "%-30s %-15s ", genpd->name, status_lookup[genpd->status]);
/*
* Modifications on the list require holding locks on both
* master and slave, so we are safe.
- * Also gpd->name is immutable.
+ * Also genpd->name is immutable.
*/
- list_for_each_entry(link, &gpd->master_links, master_node) {
+ list_for_each_entry(link, &genpd->master_links, master_node) {
seq_printf(s, "%s", link->slave->name);
- if (!list_is_last(&link->master_node, &gpd->master_links))
+ if (!list_is_last(&link->master_node, &genpd->master_links))
seq_puts(s, ", ");
}
- list_for_each_entry(pm_data, &gpd->dev_list, list_node) {
+ list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
kobj_path = kobject_get_path(&pm_data->dev->kobj, GFP_KERNEL);
if (kobj_path == NULL)
continue;
@@ -2287,14 +2287,14 @@ static int pm_genpd_summary_one(struct seq_file *s,
seq_puts(s, "\n");
exit:
- mutex_unlock(&gpd->lock);
+ mutex_unlock(&genpd->lock);
return 0;
}
static int pm_genpd_summary_show(struct seq_file *s, void *data)
{
- struct generic_pm_domain *gpd;
+ struct generic_pm_domain *genpd;
int ret = 0;
seq_puts(s, " domain status slaves\n");
@@ -2305,8 +2305,8 @@ static int pm_genpd_summary_show(struct seq_file *s, void *data)
if (ret)
return -ERESTARTSYS;
- list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
- ret = pm_genpd_summary_one(s, gpd);
+ list_for_each_entry(genpd, &gpd_list, gpd_list_node) {
+ ret = pm_genpd_summary_one(s, genpd);
if (ret)
break;
}
drivers/base/power/wakeup.c
View filediff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index c2744b3..aab7158 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -730,6 +730,7 @@ void pm_system_wakeup(void)
pm_abort_suspend = true;
freeze_wake();
}
+EXPORT_SYMBOL_GPL(pm_system_wakeup);
void pm_wakeup_clear(void)
{
drivers/clk/at91/pmc.c
View filediff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index f07c815..3f27d21 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -89,12 +89,29 @@ static int pmc_irq_set_type(struct irq_data *d, unsigned type)
return 0;
}
+static void pmc_irq_suspend(struct irq_data *d)
+{
+ struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+
+ pmc->imr = pmc_read(pmc, AT91_PMC_IMR);
+ pmc_write(pmc, AT91_PMC_IDR, pmc->imr);
+}
+
+static void pmc_irq_resume(struct irq_data *d)
+{
+ struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+
+ pmc_write(pmc, AT91_PMC_IER, pmc->imr);
+}
+
static struct irq_chip pmc_irq = {
.name = "PMC",
.irq_disable = pmc_irq_mask,
.irq_mask = pmc_irq_mask,
.irq_unmask = pmc_irq_unmask,
.irq_set_type = pmc_irq_set_type,
+ .irq_suspend = pmc_irq_suspend,
+ .irq_resume = pmc_irq_resume,
};
static struct lock_class_key pmc_lock_class;
@@ -224,7 +241,8 @@ static struct at91_pmc *__init at91_pmc_init(struct device_node *np,
goto out_free_pmc;
pmc_write(pmc, AT91_PMC_IDR, 0xffffffff);
- if (request_irq(pmc->virq, pmc_irq_handler, IRQF_SHARED, "pmc", pmc))
+ if (request_irq(pmc->virq, pmc_irq_handler,
+ IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc))
goto out_remove_irqdomain;
return pmc;
drivers/clk/at91/pmc.h
View filediff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 52d2041..69abb08 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -33,6 +33,7 @@ struct at91_pmc {
spinlock_t lock;
const struct at91_pmc_caps *caps;
struct irq_domain *irqdomain;
+ u32 imr;
};
static inline void pmc_lock(struct at91_pmc *pmc)
drivers/cpufreq/ppc-corenet-cpufreq.c
View filediff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
index bee5df7..7cb4b76 100644
--- a/drivers/cpufreq/ppc-corenet-cpufreq.c
+++ b/drivers/cpufreq/ppc-corenet-cpufreq.c
@@ -22,6 +22,8 @@
#include <linux/smp.h>
#include <sysdev/fsl_soc.h>
+#include <asm/smp.h> /* for get_hard_smp_processor_id() in UP configs */
+
/**
* struct cpu_data - per CPU data struct
* @parent: the parent node of cpu clock
drivers/cpuidle/cpuidle.c
View filediff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 4d53458..080bd2d 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -44,6 +44,12 @@ void disable_cpuidle(void)
off = 1;
}
+bool cpuidle_not_available(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev)
+{
+ return off || !initialized || !drv || !dev || !dev->enabled;
+}
+
/**
* cpuidle_play_dead - cpu off-lining
*
@@ -66,14 +72,8 @@ int cpuidle_play_dead(void)
return -ENODEV;
}
-/**
- * cpuidle_find_deepest_state - Find deepest state meeting specific conditions.
- * @drv: cpuidle driver for the given CPU.
- * @dev: cpuidle device for the given CPU.
- * @freeze: Whether or not the state should be suitable for suspend-to-idle.
- */
-static int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
- struct cpuidle_device *dev, bool freeze)
+static int find_deepest_state(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev, bool freeze)
{
unsigned int latency_req = 0;
int i, ret = freeze ? -1 : CPUIDLE_DRIVER_STATE_START - 1;
@@ -92,6 +92,17 @@ static int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
return ret;
}
+/**
+ * cpuidle_find_deepest_state - Find the deepest available idle state.
+ * @drv: cpuidle driver for the given CPU.
+ * @dev: cpuidle device for the given CPU.
+ */
+int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev)
+{
+ return find_deepest_state(drv, dev, false);
+}
+
static void enter_freeze_proper(struct cpuidle_driver *drv,
struct cpuidle_device *dev, int index)
{
@@ -113,15 +124,14 @@ static void enter_freeze_proper(struct cpuidle_driver *drv,
/**
* cpuidle_enter_freeze - Enter an idle state suitable for suspend-to-idle.
+ * @drv: cpuidle driver for the given CPU.
+ * @dev: cpuidle device for the given CPU.
*
* If there are states with the ->enter_freeze callback, find the deepest of
- * them and enter it with frozen tick. Otherwise, find the deepest state
- * available and enter it normally.
+ * them and enter it with frozen tick.
*/
-void cpuidle_enter_freeze(void)
+int cpuidle_enter_freeze(struct cpuidle_driver *drv, struct cpuidle_device *dev)
{
- struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
- struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
int index;
/*
@@ -129,24 +139,11 @@ void cpuidle_enter_freeze(void)
* that interrupts won't be enabled when it exits and allows the tick to
* be frozen safely.
*/
- index = cpuidle_find_deepest_state(drv, dev, true);
- if (index >= 0) {
- enter_freeze_proper(drv, dev, index);
- return;
- }
-
- /*
- * It is not safe to freeze the tick, find the deepest state available
- * at all and try to enter it normally.
- */
- index = cpuidle_find_deepest_state(drv, dev, false);
+ index = find_deepest_state(drv, dev, true);
if (index >= 0)
- cpuidle_enter(drv, dev, index);
- else
- arch_cpu_idle();
+ enter_freeze_proper(drv, dev, index);
- /* Interrupts are enabled again here. */
- local_irq_disable();
+ return index;
}
/**
@@ -205,12 +202,6 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
*/
int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
{
- if (off || !initialized)
- return -ENODEV;
-
- if (!drv || !dev || !dev->enabled)
- return -EBUSY;
-
return cpuidle_curr_governor->select(drv, dev);
}
drivers/pci/host/pci-versatile.c
View filediff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c
index 1ec694a..464bf49 100644
--- a/drivers/pci/host/pci-versatile.c
+++ b/drivers/pci/host/pci-versatile.c
@@ -80,7 +80,7 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev,
if (err)
return err;
- resource_list_for_each_entry(win, res, list) {
+ resource_list_for_each_entry(win, res) {
struct resource *parent, *res = win->res;
switch (resource_type(res)) {
drivers/rtc/rtc-at91rm9200.c
View filediff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 70a5d94..b4f7744 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -31,6 +31,7 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/suspend.h>
#include <linux/uaccess.h>
#include "rtc-at91rm9200.h"
@@ -54,6 +55,10 @@ static void __iomem *at91_rtc_regs;
static int irq;
static DEFINE_SPINLOCK(at91_rtc_lock);
static u32 at91_rtc_shadow_imr;
+static bool suspended;
+static DEFINE_SPINLOCK(suspended_lock);
+static unsigned long cached_events;
+static u32 at91_rtc_imr;
static void at91_rtc_write_ier(u32 mask)
{
@@ -290,7 +295,9 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
struct rtc_device *rtc = platform_get_drvdata(pdev);
unsigned int rtsr;
unsigned long events = 0;
+ int ret = IRQ_NONE;
+ spin_lock(&suspended_lock);
rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read_imr();
if (rtsr) { /* this interrupt is shared! Is it ours? */
if (rtsr & AT91_RTC_ALARM)
@@ -304,14 +311,22 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
at91_rtc_write(AT91_RTC_SCCR, rtsr); /* clear status reg */
- rtc_update_irq(rtc, 1, events);
+ if (!suspended) {
+ rtc_update_irq(rtc, 1, events);
- dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n", __func__,
- events >> 8, events & 0x000000FF);
+ dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n",
+ __func__, events >> 8, events & 0x000000FF);
+ } else {
+ cached_events |= events;
+ at91_rtc_write_idr(at91_rtc_imr);
+ pm_system_wakeup();
+ }
- return IRQ_HANDLED;
+ ret = IRQ_HANDLED;
}
- return IRQ_NONE; /* not handled */
+ spin_lock(&suspended_lock);
+
+ return ret;
}
static const struct at91_rtc_config at91rm9200_config = {
@@ -401,8 +416,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
AT91_RTC_CALEV);
ret = devm_request_irq(&pdev->dev, irq, at91_rtc_interrupt,
- IRQF_SHARED,
- "at91_rtc", pdev);
+ IRQF_SHARED | IRQF_COND_SUSPEND,
+ "at91_rtc", pdev);
if (ret) {
dev_err(&pdev->dev, "IRQ %d already in use.\n", irq);
return ret;
@@ -454,8 +469,6 @@ static void at91_rtc_shutdown(struct platform_device *pdev)
/* AT91RM9200 RTC Power management control */
-static u32 at91_rtc_imr;
-
static int at91_rtc_suspend(struct device *dev)
{
/* this IRQ is shared with DBGU and other hardware which isn't
@@ -464,21 +477,42 @@ static int at91_rtc_suspend(struct device *dev)
at91_rtc_imr = at91_rtc_read_imr()
& (AT91_RTC_ALARM|AT91_RTC_SECEV);
if (at91_rtc_imr) {
- if (device_may_wakeup(dev))
+ if (device_may_wakeup(dev)) {
+ unsigned long flags;
+
enable_irq_wake(irq);
- else
+
+ spin_lock_irqsave(&suspended_lock, flags);
+ suspended = true;
+ spin_unlock_irqrestore(&suspended_lock, flags);
+ } else {
at91_rtc_write_idr(at91_rtc_imr);
+ }
}
return 0;
}
static int at91_rtc_resume(struct device *dev)
{
+ struct rtc_device *rtc = dev_get_drvdata(dev);
+
if (at91_rtc_imr) {
- if (device_may_wakeup(dev))
+ if (device_may_wakeup(dev)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&suspended_lock, flags);
+
+ if (cached_events) {
+ rtc_update_irq(rtc, 1, cached_events);
+ cached_events = 0;
+ }
+
+ suspended = false;
+ spin_unlock_irqrestore(&suspended_lock, flags);
+
disable_irq_wake(irq);
- else
- at91_rtc_write_ier(at91_rtc_imr);
+ }
+ at91_rtc_write_ier(at91_rtc_imr);
}
return 0;
}
drivers/rtc/rtc-at91sam9.c
View filediff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 2183fd2..5ccaee3 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -23,6 +23,7 @@
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
+#include <linux/suspend.h>
#include <linux/clk.h>
/*
@@ -77,6 +78,9 @@ struct sam9_rtc {
unsigned int gpbr_offset;
int irq;
struct clk *sclk;
+ bool suspended;
+ unsigned long events;
+ spinlock_t lock;
};
#define rtt_readl(rtc, field) \
@@ -271,14 +275,9 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
-/*
- * IRQ handler for the RTC
- */
-static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
+static irqreturn_t at91_rtc_cache_events(struct sam9_rtc *rtc)
{
- struct sam9_rtc *rtc = _rtc;
u32 sr, mr;
- unsigned long events = 0;
/* Shared interrupt may be for another device. Note: reading
* SR clears it, so we must only read it in this irq handler!
@@ -290,18 +289,54 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
/* alarm status */
if (sr & AT91_RTT_ALMS)
- events |= (RTC_AF | RTC_IRQF);
+ rtc->events |= (RTC_AF | RTC_IRQF);
/* timer update/increment */
if (sr & AT91_RTT_RTTINC)
- events |= (RTC_UF | RTC_IRQF);
+ rtc->events |= (RTC_UF | RTC_IRQF);
+
+ return IRQ_HANDLED;
+}
+
+static void at91_rtc_flush_events(struct sam9_rtc *rtc)
+{
This diff is incomplete. Download the complete patch.
drivers/tty/serial/atmel_serial.c
View fileThis diff is incomplete. Download the complete patch.
drivers/watchdog/at91sam9_wdt.c
View fileThis diff is incomplete. Download the complete patch.
include/linux/cpuidle.h
View fileThis diff is incomplete. Download the complete patch.
include/linux/interrupt.h
View fileThis diff is incomplete. Download the complete patch.
include/linux/irqdesc.h
View fileThis diff is incomplete. Download the complete patch.
kernel/irq/manage.c
View fileThis diff is incomplete. Download the complete patch.
kernel/irq/pm.c
View fileThis diff is incomplete. Download the complete patch.
kernel/sched/idle.c
View fileThis diff is incomplete. Download the complete patch.