Commit 103cf0e5 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'pm-cpuidle' and 'pm-tools'

* pm-cpuidle:
  cpuidle: poll_state: Avoid invoking local_clock() too often
  PM: cpuidle/suspend: Add s2idle usage and time state attributes
  cpuidle: Enable coupled cpuidle support on Exynos3250 platform
  cpuidle: poll_state: Add time limit to poll_idle()
  ARM: cpuidle: Drop memory allocation error message from arm_idle_init_cpu()

* pm-tools:
  pm-graph: AnalyzeSuspend v5.0
  pm-graph: AnalyzeBoot v2.2
  pm-graph: config files and installer
Loading
Loading
Loading
Loading
+25 −0
Original line number Original line Diff line number Diff line
@@ -198,6 +198,31 @@ Description:
		time (in microseconds) this cpu should spend in this idle state
		time (in microseconds) this cpu should spend in this idle state
		to make the transition worth the effort.
		to make the transition worth the effort.


What:		/sys/devices/system/cpu/cpuX/cpuidle/stateN/s2idle/
Date:		March 2018
KernelVersion:	v4.17
Contact:	Linux power management list <linux-pm@vger.kernel.org>
Description:
		Idle state usage statistics related to suspend-to-idle.

		This attribute group is only present for states that can be
		used in suspend-to-idle with suspended timekeeping.

What:		/sys/devices/system/cpu/cpuX/cpuidle/stateN/s2idle/time
Date:		March 2018
KernelVersion:	v4.17
Contact:	Linux power management list <linux-pm@vger.kernel.org>
Description:
		Total time spent by the CPU in suspend-to-idle (with scheduler
		tick suspended) after requesting this state.

What:		/sys/devices/system/cpu/cpuX/cpuidle/stateN/s2idle/usage
Date:		March 2018
KernelVersion:	v4.17
Contact:	Linux power management list <linux-pm@vger.kernel.org>
Description:
		Total number of times this state has been requested by the CPU
		while entering suspend-to-idle.


What:		/sys/devices/system/cpu/cpu#/cpufreq/*
What:		/sys/devices/system/cpu/cpu#/cpufreq/*
Date:		pre-git history
Date:		pre-git history
+0 −1
Original line number Original line Diff line number Diff line
@@ -129,7 +129,6 @@ static int __init arm_idle_init_cpu(int cpu)


	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
	if (!dev) {
		pr_err("Failed to allocate cpuidle device\n");
		ret = -ENOMEM;
		ret = -ENOMEM;
		goto out_unregister_drv;
		goto out_unregister_drv;
	}
	}
+2 −1
Original line number Original line Diff line number Diff line
@@ -117,7 +117,8 @@ static int exynos_cpuidle_probe(struct platform_device *pdev)
	int ret;
	int ret;


	if (IS_ENABLED(CONFIG_SMP) &&
	if (IS_ENABLED(CONFIG_SMP) &&
	    of_machine_is_compatible("samsung,exynos4210")) {
	    (of_machine_is_compatible("samsung,exynos4210") ||
	     of_machine_is_compatible("samsung,exynos3250"))) {
		exynos_cpuidle_pdata = pdev->dev.platform_data;
		exynos_cpuidle_pdata = pdev->dev.platform_data;


		ret = cpuidle_register(&exynos_coupled_idle_driver,
		ret = cpuidle_register(&exynos_coupled_idle_driver,
+9 −0
Original line number Original line Diff line number Diff line
@@ -131,6 +131,10 @@ int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
static void enter_s2idle_proper(struct cpuidle_driver *drv,
static void enter_s2idle_proper(struct cpuidle_driver *drv,
				struct cpuidle_device *dev, int index)
				struct cpuidle_device *dev, int index)
{
{
	ktime_t time_start, time_end;

	time_start = ns_to_ktime(local_clock());

	/*
	/*
	 * trace_suspend_resume() called by tick_freeze() for the last CPU
	 * trace_suspend_resume() called by tick_freeze() for the last CPU
	 * executing it contains RCU usage regarded as invalid in the idle
	 * executing it contains RCU usage regarded as invalid in the idle
@@ -152,6 +156,11 @@ static void enter_s2idle_proper(struct cpuidle_driver *drv,
	 */
	 */
	RCU_NONIDLE(tick_unfreeze());
	RCU_NONIDLE(tick_unfreeze());
	start_critical_timings();
	start_critical_timings();

	time_end = ns_to_ktime(local_clock());

	dev->states_usage[index].s2idle_time += ktime_us_delta(time_end, time_start);
	dev->states_usage[index].s2idle_usage++;
}
}


/**
/**
+16 −1
Original line number Original line Diff line number Diff line
@@ -6,15 +6,30 @@


#include <linux/cpuidle.h>
#include <linux/cpuidle.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/sched/clock.h>
#include <linux/sched/idle.h>
#include <linux/sched/idle.h>


#define POLL_IDLE_TIME_LIMIT	(TICK_NSEC / 16)
#define POLL_IDLE_RELAX_COUNT	200

static int __cpuidle poll_idle(struct cpuidle_device *dev,
static int __cpuidle poll_idle(struct cpuidle_device *dev,
			       struct cpuidle_driver *drv, int index)
			       struct cpuidle_driver *drv, int index)
{
{
	u64 time_start = local_clock();

	local_irq_enable();
	local_irq_enable();
	if (!current_set_polling_and_test()) {
	if (!current_set_polling_and_test()) {
		while (!need_resched())
		unsigned int loop_count = 0;

		while (!need_resched()) {
			cpu_relax();
			cpu_relax();
			if (loop_count++ < POLL_IDLE_RELAX_COUNT)
				continue;

			loop_count = 0;
			if (local_clock() - time_start > POLL_IDLE_TIME_LIMIT)
				break;
		}
	}
	}
	current_clr_polling();
	current_clr_polling();


Loading