cregit-Linux how code gets into the kernel

Release 4.11 arch/arm/mach-tegra/cpuidle-tegra20.c

/*
 * CPU idle driver for Tegra CPUs
 *
 * Copyright (c) 2010-2012, NVIDIA Corporation.
 * Copyright (c) 2011 Google, Inc.
 * Author: Colin Cross <ccross@android.com>
 *         Gary King <gking@nvidia.com>
 *
 * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#include <linux/clk/tegra.h>
#include <linux/tick.h>
#include <linux/cpuidle.h>
#include <linux/cpu_pm.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <asm/cpuidle.h>
#include <asm/smp_plat.h>
#include <asm/suspend.h>

#include "cpuidle.h"
#include "flowctrl.h"
#include "iomap.h"
#include "irq.h"
#include "pm.h"
#include "reset.h"
#include "sleep.h"

#ifdef CONFIG_PM_SLEEP

static bool abort_flag;

static atomic_t abort_barrier;
static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
				    struct cpuidle_driver *drv,
				    int index);

#define TEGRA20_MAX_STATES 2
#else

#define TEGRA20_MAX_STATES 1
#endif


static struct cpuidle_driver tegra_idle_driver = {
	.name = "tegra_idle",
	.owner = THIS_MODULE,
	.states = {
		ARM_CPUIDLE_WFI_STATE_PWR(600),
#ifdef CONFIG_PM_SLEEP
		{
			.enter            = tegra20_idle_lp2_coupled,
			.exit_latency     = 5000,
			.target_residency = 10000,
			.power_usage      = 0,
			.flags            = CPUIDLE_FLAG_COUPLED,
			.name             = "powered-down",
			.desc             = "CPU power gated",
                },
#endif
	},
	.state_count = TEGRA20_MAX_STATES,
	.safe_state_index = 0,
};

#ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_SMP

static int tegra20_reset_sleeping_cpu_1(void) { int ret = 0; tegra_pen_lock(); if (readb(tegra20_cpu1_resettable_status) == CPU_RESETTABLE) tegra20_cpu_shutdown(1); else ret = -EINVAL; tegra_pen_unlock(); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo4095.24%150.00%
Dmitry Osipenko24.76%150.00%
Total42100.00%2100.00%


static void tegra20_wake_cpu1_from_reset(void) { tegra_pen_lock(); tegra20_cpu_clear_resettable(); /* enable cpu clock on cpu */ tegra_enable_cpu_clock(1); /* take the CPU out of reset */ tegra_cpu_out_of_reset(1); /* unhalt the cpu */ flowctrl_write_cpu_halt(1, 0); tegra_pen_unlock(); }

Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo37100.00%1100.00%
Total37100.00%1100.00%


static int tegra20_reset_cpu_1(void) { if (!cpu_online(1) || !tegra20_reset_sleeping_cpu_1()) return 0; tegra20_wake_cpu1_from_reset(); return -EBUSY; }

Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo30100.00%1100.00%
Total30100.00%1100.00%

#else
static inline void tegra20_wake_cpu1_from_reset(void) { }

Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo8100.00%1100.00%
Total8100.00%1100.00%


static inline int tegra20_reset_cpu_1(void) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo12100.00%1100.00%
Total12100.00%1100.00%

#endif
static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { while (tegra20_cpu_is_resettable_soon()) cpu_relax(); if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready()) return false; tick_broadcast_enter(); tegra_idle_lp2_last(); tick_broadcast_exit(); if (cpu_online(1)) tegra20_wake_cpu1_from_reset(); return true; }

Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo5793.44%266.67%
Thomas Gleixner46.56%133.33%
Total61100.00%3100.00%

#ifdef CONFIG_SMP
static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { tick_broadcast_enter(); cpu_suspend(0, tegra20_sleep_cpu_secondary_finish); tegra20_cpu_clear_resettable(); tick_broadcast_exit(); return true; }

Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo3489.47%150.00%
Thomas Gleixner410.53%150.00%
Total38100.00%2100.00%

#else
static inline bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { return true; }

Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo23100.00%1100.00%
Total23100.00%1100.00%

#endif
static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { bool entered_lp2 = false; if (tegra_pending_sgi()) ACCESS_ONCE(abort_flag) = true; cpuidle_coupled_parallel_barrier(dev, &abort_barrier); if (abort_flag) { cpuidle_coupled_parallel_barrier(dev, &abort_barrier); abort_flag = false; /* clean flag for next coming */ return -EINTR; } local_fiq_disable(); tegra_set_cpu_in_lp2(); cpu_pm_enter(); if (dev->cpu == 0) entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index); else entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index); cpu_pm_exit(); tegra_clear_cpu_in_lp2(); local_fiq_enable(); smp_rmb(); return entered_lp2 ? index : 0; }

Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo126100.00%3100.00%
Total126100.00%3100.00%

#endif /* * Tegra20 HW appears to have a bug such that PCIe device interrupts, whether * they are legacy IRQs or MSI, are lost when LP2 is enabled. To work around * this, simply disable LP2 if the PCI driver and DT node are both enabled. */
void tegra20_cpuidle_pcie_irqs_in_use(void) { pr_info_once( "Disabling cpuidle LP2 state, since PCIe IRQs are in use\n"); tegra_idle_driver.states[1].disabled = true; }

Contributors

PersonTokensPropCommitsCommitProp
Stephen Warren23100.00%1100.00%
Total23100.00%1100.00%


int __init tegra20_cpuidle_init(void) { return cpuidle_register(&tegra_idle_driver, cpu_possible_mask); }

Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo1588.24%266.67%
Daniel Lezcano211.76%133.33%
Total17100.00%3100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Joseph Lo52486.33%541.67%
Daniel Lezcano325.27%216.67%
Stephen Warren243.95%18.33%
Thierry Reding132.14%216.67%
Thomas Gleixner91.48%18.33%
Dmitry Osipenko50.82%18.33%
Total607100.00%12100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.