Skip to content

Commit

Permalink
Merge tag 'pm+acpi-3.16-rc1-2' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/rafael/linux-pm

Pull more ACPI and power management updates from Rafael Wysocki:
 "These are fixups on top of the previous PM+ACPI pull request,
  regression fixes (ACPI hotplug, cpufreq ppc-corenet), other bug fixes
  (ACPI reset, cpufreq), new PM trace points for system suspend
  profiling and a copyright notice update.

  Specifics:

   - I didn't remember correctly that the Hans de Goede's ACPI video
     patches actually didn't flip the video.use_native_backlight
     default, although we had discussed that and decided to do that.
     Since I said we would do that in the previous PM+ACPI pull request,
     make that change for real now.

   - ACPI bus check notifications for PCI host bridges don't cause the
     bus below the host bridge to be checked for changes as they should
     because of a mistake in the ACPI-based PCI hotplug (ACPIPHP)
     subsystem that forgets to add hotplug contexts to PCI host bridge
     ACPI device objects.  Create hotplug contexts for PCI host bridges
     too as appropriate.

   - Revert recent cpufreq commit related to the big.LITTLE cpufreq
     driver that breaks arm64 builds.

   - Fix for a regression in the ppc-corenet cpufreq driver introduced
     during the 3.15 cycle and causing the driver to use the remainder
     from do_div instead of the quotient.  From Ed Swarthout.

   - Resets triggered by panic activate a BUG_ON() in vmalloc.c on
     systems where the ACPI reset register is located in memory address
     space.  Fix from Randy Wright.

   - Fix for a problem with cpufreq governors that decisions made by
     them may be suboptimal due to the fact that deferrable timers are
     used by them for CPU load sampling.  From Srivatsa S Bhat.

   - Fix for a problem with the Tegra cpufreq driver where the CPU
     frequency is temporarily switched to a "stable" level that is
     different from both the initial and target frequencies during
     transitions which causes udelay() to expire earlier than it should
     sometimes.  From Viresh Kumar.

   - New trace points and rework of some existing trace points for
     system suspend/resume profiling from Todd Brandt.

   - Assorted cpufreq fixes and cleanups from Stratos Karafotis and
     Viresh Kumar.

   - Copyright notice update for suspend-and-cpuhotplug.txt from
     Srivatsa S Bhat"

* tag 'pm+acpi-3.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI / hotplug / PCI: Add hotplug contexts to PCI host bridges
  PM / sleep: trace events for device PM callbacks
  cpufreq: cpufreq-cpu0: remove dependency on THERMAL and REGULATOR
  cpufreq: tegra: update comment for clarity
  cpufreq: intel_pstate: Remove duplicate CPU ID check
  cpufreq: Mark CPU0 driver with CPUFREQ_NEED_INITIAL_FREQ_CHECK flag
  PM / Documentation: Update copyright in suspend-and-cpuhotplug.txt
  cpufreq: governor: remove copy_prev_load from 'struct cpu_dbs_common_info'
  cpufreq: governor: Be friendly towards latency-sensitive bursty workloads
  PM / sleep: trace events for suspend/resume
  cpufreq: ppc-corenet-cpu-freq: do_div use quotient
  Revert "cpufreq: Enable big.LITTLE cpufreq driver on arm64"
  cpufreq: Tegra: implement intermediate frequency callbacks
  cpufreq: add support for intermediate (stable) frequencies
  ACPI / video: Change the default for video.use_native_backlight to 1
  ACPI: Fix bug when ACPI reset register is implemented in system memory
  • Loading branch information
Linus Torvalds committed Jun 12, 2014
2 parents 7c574cf + d715a22 commit 19c1940
Show file tree
Hide file tree
Showing 24 changed files with 437 additions and 113 deletions.
29 changes: 27 additions & 2 deletions Documentation/cpu-freq/cpu-drivers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Contents:
1.4 target/target_index or setpolicy?
1.5 target/target_index
1.6 setpolicy
1.7 get_intermediate and target_intermediate
2. Frequency Table Helpers


Expand Down Expand Up @@ -79,6 +80,10 @@ cpufreq_driver.attr - A pointer to a NULL-terminated list of
"struct freq_attr" which allow to
export values to sysfs.

cpufreq_driver.get_intermediate
and target_intermediate Used to switch to stable frequency while
changing CPU frequency.


1.2 Per-CPU Initialization
--------------------------
Expand Down Expand Up @@ -151,7 +156,7 @@ Some cpufreq-capable processors switch the frequency between certain
limits on their own. These shall use the ->setpolicy call


1.4. target/target_index
1.5. target/target_index
-------------

The target_index call has two arguments: struct cpufreq_policy *policy,
Expand All @@ -160,6 +165,9 @@ and unsigned int index (into the exposed frequency table).
The CPUfreq driver must set the new frequency when called here. The
actual frequency must be determined by freq_table[index].frequency.

It should always restore to earlier frequency (i.e. policy->restore_freq) in
case of errors, even if we switched to intermediate frequency earlier.

Deprecated:
----------
The target call has three arguments: struct cpufreq_policy *policy,
Expand All @@ -179,7 +187,7 @@ Here again the frequency table helper might assist you - see section 2
for details.


1.5 setpolicy
1.6 setpolicy
---------------

The setpolicy call only takes a struct cpufreq_policy *policy as
Expand All @@ -190,6 +198,23 @@ setting when policy->policy is CPUFREQ_POLICY_PERFORMANCE, and a
powersaving-oriented setting when CPUFREQ_POLICY_POWERSAVE. Also check
the reference implementation in drivers/cpufreq/longrun.c

1.7 get_intermediate and target_intermediate
--------------------------------------------

Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION unset.

get_intermediate should return a stable intermediate frequency platform wants to
switch to, and target_intermediate() should set CPU to to that frequency, before
jumping to the frequency corresponding to 'index'. Core will take care of
sending notifications and driver doesn't have to handle them in
target_intermediate() or target_index().

Drivers can return '0' from get_intermediate() in case they don't wish to switch
to intermediate frequency for some target frequency. In that case core will
directly call ->target_index().

NOTE: ->target_index() should restore to policy->restore_freq in case of
failures as core would send notifications for that.


2. Frequency Table Helpers
Expand Down
2 changes: 1 addition & 1 deletion Documentation/power/suspend-and-cpuhotplug.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Interaction of Suspend code (S3) with the CPU hotplug infrastructure

(C) 2011 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
(C) 2011 - 2014 Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>


I. How does the regular CPU hotplug code differ from how the Suspend-to-RAM
Expand Down
12 changes: 12 additions & 0 deletions drivers/acpi/osl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,16 @@ acpi_status __init acpi_os_initialize(void)
acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) {
/*
* Use acpi_os_map_generic_address to pre-map the reset
* register if it's in system memory.
*/
int rv;

rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register);
pr_debug(PREFIX "%s: map reset_reg status %d\n", __func__, rv);
}

return AE_OK;
}
Expand Down Expand Up @@ -1838,6 +1848,8 @@ acpi_status acpi_os_terminate(void)
acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block);
acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)
acpi_os_unmap_generic_address(&acpi_gbl_FADT.reset_register);

destroy_workqueue(kacpid_wq);
destroy_workqueue(kacpi_notify_wq);
Expand Down
3 changes: 3 additions & 0 deletions drivers/acpi/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/acpi.h>
#include <linux/module.h>
#include <asm/io.h>
#include <trace/events/power.h>

#include "internal.h"
#include "sleep.h"
Expand Down Expand Up @@ -501,6 +502,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)

ACPI_FLUSH_CPU_CACHE();

trace_suspend_resume(TPS("acpi_suspend"), acpi_state, true);
switch (acpi_state) {
case ACPI_STATE_S1:
barrier();
Expand All @@ -516,6 +518,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
pr_info(PREFIX "Low-level resume complete\n");
break;
}
trace_suspend_resume(TPS("acpi_suspend"), acpi_state, false);

/* This violates the spec but is required for bug compatibility. */
acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ module_param(allow_duplicates, bool, 0644);
* For Windows 8 systems: used to decide if video module
* should skip registering backlight interface of its own.
*/
static int use_native_backlight_param = -1;
static int use_native_backlight_param = 1;
module_param_named(use_native_backlight, use_native_backlight_param, int, 0444);
static bool use_native_backlight_dmi = false;

Expand Down
30 changes: 26 additions & 4 deletions drivers/base/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,6 @@ static void initcall_debug_report(struct device *dev, ktime_t calltime,
pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
error, (unsigned long long)nsecs >> 10);
}

trace_device_pm_report_time(dev, info, nsecs, pm_verb(state.event),
error);
}

/**
Expand Down Expand Up @@ -387,7 +384,9 @@ static int dpm_run_callback(pm_callback_t cb, struct device *dev,
calltime = initcall_debug_start(dev);

pm_dev_dbg(dev, state, info);
trace_device_pm_callback_start(dev, info, state.event);
error = cb(dev);
trace_device_pm_callback_end(dev, error);
suspend_report_result(cb, error);

initcall_debug_report(dev, calltime, error, state, info);
Expand Down Expand Up @@ -545,6 +544,7 @@ static void dpm_resume_noirq(pm_message_t state)
struct device *dev;
ktime_t starttime = ktime_get();

trace_suspend_resume(TPS("dpm_resume_noirq"), state.event, true);
mutex_lock(&dpm_list_mtx);
pm_transition = state;

Expand Down Expand Up @@ -587,6 +587,7 @@ static void dpm_resume_noirq(pm_message_t state)
dpm_show_time(starttime, state, "noirq");
resume_device_irqs();
cpuidle_resume();
trace_suspend_resume(TPS("dpm_resume_noirq"), state.event, false);
}

/**
Expand Down Expand Up @@ -664,6 +665,7 @@ static void dpm_resume_early(pm_message_t state)
struct device *dev;
ktime_t starttime = ktime_get();

trace_suspend_resume(TPS("dpm_resume_early"), state.event, true);
mutex_lock(&dpm_list_mtx);
pm_transition = state;

Expand Down Expand Up @@ -703,6 +705,7 @@ static void dpm_resume_early(pm_message_t state)
mutex_unlock(&dpm_list_mtx);
async_synchronize_full();
dpm_show_time(starttime, state, "early");
trace_suspend_resume(TPS("dpm_resume_early"), state.event, false);
}

/**
Expand Down Expand Up @@ -834,6 +837,7 @@ void dpm_resume(pm_message_t state)
struct device *dev;
ktime_t starttime = ktime_get();

trace_suspend_resume(TPS("dpm_resume"), state.event, true);
might_sleep();

mutex_lock(&dpm_list_mtx);
Expand Down Expand Up @@ -875,6 +879,7 @@ void dpm_resume(pm_message_t state)
dpm_show_time(starttime, state, NULL);

cpufreq_resume();
trace_suspend_resume(TPS("dpm_resume"), state.event, false);
}

/**
Expand Down Expand Up @@ -913,7 +918,9 @@ static void device_complete(struct device *dev, pm_message_t state)

if (callback) {
pm_dev_dbg(dev, state, info);
trace_device_pm_callback_start(dev, info, state.event);
callback(dev);
trace_device_pm_callback_end(dev, 0);
}

device_unlock(dev);
Expand All @@ -932,6 +939,7 @@ void dpm_complete(pm_message_t state)
{
struct list_head list;

trace_suspend_resume(TPS("dpm_complete"), state.event, true);
might_sleep();

INIT_LIST_HEAD(&list);
Expand All @@ -951,6 +959,7 @@ void dpm_complete(pm_message_t state)
}
list_splice(&list, &dpm_list);
mutex_unlock(&dpm_list_mtx);
trace_suspend_resume(TPS("dpm_complete"), state.event, false);
}

/**
Expand Down Expand Up @@ -1086,6 +1095,7 @@ static int dpm_suspend_noirq(pm_message_t state)
ktime_t starttime = ktime_get();
int error = 0;

trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, true);
cpuidle_pause();
suspend_device_irqs();
mutex_lock(&dpm_list_mtx);
Expand Down Expand Up @@ -1126,6 +1136,7 @@ static int dpm_suspend_noirq(pm_message_t state)
} else {
dpm_show_time(starttime, state, "noirq");
}
trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, false);
return error;
}

Expand Down Expand Up @@ -1222,6 +1233,7 @@ static int dpm_suspend_late(pm_message_t state)
ktime_t starttime = ktime_get();
int error = 0;

trace_suspend_resume(TPS("dpm_suspend_late"), state.event, true);
mutex_lock(&dpm_list_mtx);
pm_transition = state;
async_error = 0;
Expand Down Expand Up @@ -1257,6 +1269,7 @@ static int dpm_suspend_late(pm_message_t state)
} else {
dpm_show_time(starttime, state, "late");
}
trace_suspend_resume(TPS("dpm_suspend_late"), state.event, false);
return error;
}

Expand Down Expand Up @@ -1295,7 +1308,9 @@ static int legacy_suspend(struct device *dev, pm_message_t state,

calltime = initcall_debug_start(dev);

trace_device_pm_callback_start(dev, info, state.event);
error = cb(dev, state);
trace_device_pm_callback_end(dev, error);
suspend_report_result(cb, error);

initcall_debug_report(dev, calltime, error, state, info);
Expand Down Expand Up @@ -1461,6 +1476,7 @@ int dpm_suspend(pm_message_t state)
ktime_t starttime = ktime_get();
int error = 0;

trace_suspend_resume(TPS("dpm_suspend"), state.event, true);
might_sleep();

cpufreq_suspend();
Expand Down Expand Up @@ -1498,6 +1514,7 @@ int dpm_suspend(pm_message_t state)
dpm_save_failed_step(SUSPEND_SUSPEND);
} else
dpm_show_time(starttime, state, NULL);
trace_suspend_resume(TPS("dpm_suspend"), state.event, false);
return error;
}

Expand Down Expand Up @@ -1549,8 +1566,11 @@ static int device_prepare(struct device *dev, pm_message_t state)
callback = dev->driver->pm->prepare;
}

if (callback)
if (callback) {
trace_device_pm_callback_start(dev, info, state.event);
ret = callback(dev);
trace_device_pm_callback_end(dev, ret);
}

device_unlock(dev);

Expand Down Expand Up @@ -1582,6 +1602,7 @@ int dpm_prepare(pm_message_t state)
{
int error = 0;

trace_suspend_resume(TPS("dpm_prepare"), state.event, true);
might_sleep();

mutex_lock(&dpm_list_mtx);
Expand Down Expand Up @@ -1612,6 +1633,7 @@ int dpm_prepare(pm_message_t state)
put_device(dev);
}
mutex_unlock(&dpm_list_mtx);
trace_suspend_resume(TPS("dpm_prepare"), state.event, false);
return error;
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/base/syscore.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <trace/events/power.h>

static LIST_HEAD(syscore_ops_list);
static DEFINE_MUTEX(syscore_ops_lock);
Expand Down Expand Up @@ -49,6 +50,7 @@ int syscore_suspend(void)
struct syscore_ops *ops;
int ret = 0;

trace_suspend_resume(TPS("syscore_suspend"), 0, true);
pr_debug("Checking wakeup interrupts\n");

/* Return error code if there are any wakeup interrupts pending. */
Expand All @@ -70,6 +72,7 @@ int syscore_suspend(void)
"Interrupts enabled after %pF\n", ops->suspend);
}

trace_suspend_resume(TPS("syscore_suspend"), 0, false);
return 0;

err_out:
Expand All @@ -92,6 +95,7 @@ void syscore_resume(void)
{
struct syscore_ops *ops;

trace_suspend_resume(TPS("syscore_resume"), 0, true);
WARN_ONCE(!irqs_disabled(),
"Interrupts enabled before system core resume.\n");

Expand All @@ -103,6 +107,7 @@ void syscore_resume(void)
WARN_ONCE(!irqs_disabled(),
"Interrupts enabled after %pF\n", ops->resume);
}
trace_suspend_resume(TPS("syscore_resume"), 0, false);
}
EXPORT_SYMBOL_GPL(syscore_resume);
#endif /* CONFIG_PM_SLEEP */
Expand Down
2 changes: 1 addition & 1 deletion drivers/cpufreq/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ config CPU_FREQ_GOV_CONSERVATIVE

config GENERIC_CPUFREQ_CPU0
tristate "Generic CPU0 cpufreq driver"
depends on HAVE_CLK && REGULATOR && OF && THERMAL && CPU_THERMAL
depends on HAVE_CLK && OF
select PM_OPP
help
This adds a generic cpufreq driver for CPU0 frequency management.
Expand Down
3 changes: 1 addition & 2 deletions drivers/cpufreq/Kconfig.arm
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
# big LITTLE core layer and glue drivers
config ARM_BIG_LITTLE_CPUFREQ
tristate "Generic ARM big LITTLE CPUfreq driver"
depends on (BIG_LITTLE && ARM_CPU_TOPOLOGY) || (ARM64 && SMP)
depends on HAVE_CLK
depends on ARM && BIG_LITTLE && ARM_CPU_TOPOLOGY && HAVE_CLK
select PM_OPP
help
This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
Expand Down
2 changes: 1 addition & 1 deletion drivers/cpufreq/cpufreq-cpu0.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ static int cpu0_cpufreq_init(struct cpufreq_policy *policy)
}

static struct cpufreq_driver cpu0_cpufreq_driver = {
.flags = CPUFREQ_STICKY,
.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify,
.target_index = cpu0_set_target,
.get = cpufreq_generic_get,
Expand Down
Loading

0 comments on commit 19c1940

Please sign in to comment.