All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] Consolidate and improve NVIDIA Tegra CPUIDLE driver(s)
@ 2019-07-11  3:13 ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

Hello,

I was spending quite some time recently trying to hunt down CPU-suspend
bug on Tegra30 SoC and in the end it was nailed. During that time I
realized that the CPU Idle drivers could get some polish and gain new
features, thus that's what this series does:

  1. Unifies Tegra20/30/114 drivers into a single driver and moves it out
     into common drivers/cpuidle/ directory.

  2. Enables CPU cluster power-down idling state on Tegra30.

In the end there is a quite nice clean up of the Tegra CPUIDLE driver(s)
and of the Tegra's arch code in general. Please review, thanks!

Changelog:

v2: - Added patches to enable the new cpuidle driver in the defconfigs:

        ARM: multi_v7_defconfig: Enable Tegra cpuidle driver
        ARM: tegra: Enable Tegra cpuidle driver in tegra_defconfig

    - Dropped patches that removed CPUIDLE_FLAG_TIMER_STOP from the idling
      states because that flag actually doesn't have any negative effects,
      but still is correct for the case of a local CPU timer on older Tegra
      SoCs:

        cpuidle: tegra: Remove CPUIDLE_FLAG_TIMER_STOP from Tegra114/124 idle-state
        cpuidle: tegra: Remove CPUIDLE_FLAG_TIMER_STOP from all states

    - The "Add unified driver for NVIDIA Tegra SoCs" patch got more polish.
      Tegra30 and Terga114 states are now squashed into a single common C7
      state (following Parker TRM terminology, see 17.2.2.2 Power Management
      States), more comments added, etc minor changes.

Dmitry Osipenko (6):
  ARM: tegra: Remove cpuidle drivers
  ARM: tegra: Expose functions required for cpuidle driver
  cpuidle: Add unified driver for NVIDIA Tegra SoCs
  cpuidle: tegra: Support CPU cluster power-down on Tegra30
  ARM: multi_v7_defconfig: Enable Tegra cpuidle driver
  ARM: tegra: Enable Tegra cpuidle driver in tegra_defconfig

 arch/arm/configs/multi_v7_defconfig    |   1 +
 arch/arm/configs/tegra_defconfig       |   1 +
 arch/arm/mach-tegra/Makefile           |  15 +-
 arch/arm/mach-tegra/cpuidle-tegra114.c |  89 --------
 arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -----------------
 arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 -----------
 arch/arm/mach-tegra/cpuidle.c          |  50 ----
 arch/arm/mach-tegra/cpuidle.h          |  21 --
 arch/arm/mach-tegra/irq.c              |  18 --
 arch/arm/mach-tegra/irq.h              |  11 -
 arch/arm/mach-tegra/platsmp.c          |   2 -
 arch/arm/mach-tegra/pm.c               |  27 +--
 arch/arm/mach-tegra/pm.h               |   4 -
 arch/arm/mach-tegra/reset-handler.S    |  11 -
 arch/arm/mach-tegra/reset.h            |   9 +-
 arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------
 arch/arm/mach-tegra/sleep.h            |  13 --
 arch/arm/mach-tegra/tegra.c            |   7 +-
 drivers/cpuidle/Kconfig.arm            |   8 +
 drivers/cpuidle/Makefile               |   1 +
 drivers/cpuidle/cpuidle-tegra.c        | 303 +++++++++++++++++++++++++
 drivers/soc/tegra/Kconfig              |   1 -
 include/linux/clk/tegra.h              |  13 ++
 include/soc/tegra/cpuidle.h            |   2 +-
 include/soc/tegra/pm.h                 |  28 +++
 25 files changed, 375 insertions(+), 794 deletions(-)
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle.h
 delete mode 100644 arch/arm/mach-tegra/irq.h
 create mode 100644 drivers/cpuidle/cpuidle-tegra.c

-- 
2.22.0

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v2 0/6] Consolidate and improve NVIDIA Tegra CPUIDLE driver(s)
@ 2019-07-11  3:13 ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

Hello,

I was spending quite some time recently trying to hunt down CPU-suspend
bug on Tegra30 SoC and in the end it was nailed. During that time I
realized that the CPU Idle drivers could get some polish and gain new
features, thus that's what this series does:

  1. Unifies Tegra20/30/114 drivers into a single driver and moves it out
     into common drivers/cpuidle/ directory.

  2. Enables CPU cluster power-down idling state on Tegra30.

In the end there is a quite nice clean up of the Tegra CPUIDLE driver(s)
and of the Tegra's arch code in general. Please review, thanks!

Changelog:

v2: - Added patches to enable the new cpuidle driver in the defconfigs:

        ARM: multi_v7_defconfig: Enable Tegra cpuidle driver
        ARM: tegra: Enable Tegra cpuidle driver in tegra_defconfig

    - Dropped patches that removed CPUIDLE_FLAG_TIMER_STOP from the idling
      states because that flag actually doesn't have any negative effects,
      but still is correct for the case of a local CPU timer on older Tegra
      SoCs:

        cpuidle: tegra: Remove CPUIDLE_FLAG_TIMER_STOP from Tegra114/124 idle-state
        cpuidle: tegra: Remove CPUIDLE_FLAG_TIMER_STOP from all states

    - The "Add unified driver for NVIDIA Tegra SoCs" patch got more polish.
      Tegra30 and Terga114 states are now squashed into a single common C7
      state (following Parker TRM terminology, see 17.2.2.2 Power Management
      States), more comments added, etc minor changes.

Dmitry Osipenko (6):
  ARM: tegra: Remove cpuidle drivers
  ARM: tegra: Expose functions required for cpuidle driver
  cpuidle: Add unified driver for NVIDIA Tegra SoCs
  cpuidle: tegra: Support CPU cluster power-down on Tegra30
  ARM: multi_v7_defconfig: Enable Tegra cpuidle driver
  ARM: tegra: Enable Tegra cpuidle driver in tegra_defconfig

 arch/arm/configs/multi_v7_defconfig    |   1 +
 arch/arm/configs/tegra_defconfig       |   1 +
 arch/arm/mach-tegra/Makefile           |  15 +-
 arch/arm/mach-tegra/cpuidle-tegra114.c |  89 --------
 arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -----------------
 arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 -----------
 arch/arm/mach-tegra/cpuidle.c          |  50 ----
 arch/arm/mach-tegra/cpuidle.h          |  21 --
 arch/arm/mach-tegra/irq.c              |  18 --
 arch/arm/mach-tegra/irq.h              |  11 -
 arch/arm/mach-tegra/platsmp.c          |   2 -
 arch/arm/mach-tegra/pm.c               |  27 +--
 arch/arm/mach-tegra/pm.h               |   4 -
 arch/arm/mach-tegra/reset-handler.S    |  11 -
 arch/arm/mach-tegra/reset.h            |   9 +-
 arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------
 arch/arm/mach-tegra/sleep.h            |  13 --
 arch/arm/mach-tegra/tegra.c            |   7 +-
 drivers/cpuidle/Kconfig.arm            |   8 +
 drivers/cpuidle/Makefile               |   1 +
 drivers/cpuidle/cpuidle-tegra.c        | 303 +++++++++++++++++++++++++
 drivers/soc/tegra/Kconfig              |   1 -
 include/linux/clk/tegra.h              |  13 ++
 include/soc/tegra/cpuidle.h            |   2 +-
 include/soc/tegra/pm.h                 |  28 +++
 25 files changed, 375 insertions(+), 794 deletions(-)
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle.h
 delete mode 100644 arch/arm/mach-tegra/irq.h
 create mode 100644 drivers/cpuidle/cpuidle-tegra.c

-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
  2019-07-11  3:13 ` Dmitry Osipenko
@ 2019-07-11  3:13   ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

Remove the old drivers to replace them cleanly with a new one later on.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/Makefile           |  13 --
 arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
 arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
 arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
 arch/arm/mach-tegra/cpuidle.c          |  50 ------
 arch/arm/mach-tegra/cpuidle.h          |  21 ---
 arch/arm/mach-tegra/irq.c              |  18 ---
 arch/arm/mach-tegra/irq.h              |  11 --
 arch/arm/mach-tegra/pm.c               |   7 -
 arch/arm/mach-tegra/pm.h               |   1 -
 arch/arm/mach-tegra/reset-handler.S    |  11 --
 arch/arm/mach-tegra/reset.h            |   9 +-
 arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
 arch/arm/mach-tegra/sleep.h            |  12 --
 arch/arm/mach-tegra/tegra.c            |   3 -
 drivers/soc/tegra/Kconfig              |   1 -
 include/soc/tegra/cpuidle.h            |   4 -
 17 files changed, 5 insertions(+), 779 deletions(-)
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle.h
 delete mode 100644 arch/arm/mach-tegra/irq.h

diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 6c1dff2eccc2..5d93a0b36866 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -8,29 +8,16 @@ obj-y					+= reset.o
 obj-y					+= reset-handler.o
 obj-y					+= sleep.o
 obj-y					+= tegra.o
-obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= sleep-tegra20.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pm-tegra20.o
-ifeq ($(CONFIG_CPU_IDLE),y)
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= cpuidle-tegra20.o
-endif
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= pm-tegra30.o
-ifeq ($(CONFIG_CPU_IDLE),y)
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= cpuidle-tegra30.o
-endif
 obj-$(CONFIG_SMP)			+= platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
 
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= sleep-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= pm-tegra30.o
-ifeq ($(CONFIG_CPU_IDLE),y)
-obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= cpuidle-tegra114.o
-endif
 obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= sleep-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= pm-tegra30.o
-ifeq ($(CONFIG_CPU_IDLE),y)
-obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= cpuidle-tegra114.o
-endif
 
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= board-paz00.o
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
deleted file mode 100644
index 5118f777fd66..000000000000
--- a/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
- */
-
-#include <asm/firmware.h>
-#include <linux/tick.h>
-#include <linux/cpuidle.h>
-#include <linux/cpu_pm.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/firmware/trusted_foundations.h>
-
-#include <asm/cpuidle.h>
-#include <asm/smp_plat.h>
-#include <asm/suspend.h>
-#include <asm/psci.h>
-
-#include "cpuidle.h"
-#include "pm.h"
-#include "sleep.h"
-
-#ifdef CONFIG_PM_SLEEP
-#define TEGRA114_MAX_STATES 2
-#else
-#define TEGRA114_MAX_STATES 1
-#endif
-
-#ifdef CONFIG_PM_SLEEP
-static int tegra114_idle_power_down(struct cpuidle_device *dev,
-				    struct cpuidle_driver *drv,
-				    int index)
-{
-	local_fiq_disable();
-
-	tegra_set_cpu_in_lp2();
-	cpu_pm_enter();
-
-	call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
-
-	/* Do suspend by ourselves if the firmware does not implement it */
-	if (call_firmware_op(do_idle, 0) == -ENOSYS)
-		cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
-
-	cpu_pm_exit();
-	tegra_clear_cpu_in_lp2();
-
-	local_fiq_enable();
-
-	return index;
-}
-
-static void tegra114_idle_enter_s2idle(struct cpuidle_device *dev,
-				       struct cpuidle_driver *drv,
-				       int index)
-{
-       tegra114_idle_power_down(dev, drv, index);
-}
-#endif
-
-static struct cpuidle_driver tegra_idle_driver = {
-	.name = "tegra_idle",
-	.owner = THIS_MODULE,
-	.state_count = TEGRA114_MAX_STATES,
-	.states = {
-		[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
-#ifdef CONFIG_PM_SLEEP
-		[1] = {
-			.enter			= tegra114_idle_power_down,
-			.enter_s2idle		= tegra114_idle_enter_s2idle,
-			.exit_latency		= 500,
-			.target_residency	= 1000,
-			.flags			= CPUIDLE_FLAG_TIMER_STOP,
-			.power_usage		= 0,
-			.name			= "powered-down",
-			.desc			= "CPU power gated",
-		},
-#endif
-	},
-};
-
-int __init tegra114_cpuidle_init(void)
-{
-	if (!psci_smp_available())
-		return cpuidle_register(&tegra_idle_driver, NULL);
-
-	return 0;
-}
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
deleted file mode 100644
index 2447427cb4a8..000000000000
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ /dev/null
@@ -1,212 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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>
- */
-
-#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 <soc/tegra/flowctrl.h>
-
-#include <asm/cpuidle.h>
-#include <asm/smp_plat.h>
-#include <asm/suspend.h>
-
-#include "cpuidle.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 |
-			                    CPUIDLE_FLAG_TIMER_STOP,
-			.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;
-}
-
-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();
-}
-
-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;
-}
-#else
-static inline void tegra20_wake_cpu1_from_reset(void)
-{
-}
-
-static inline int tegra20_reset_cpu_1(void)
-{
-	return 0;
-}
-#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;
-
-	tegra_idle_lp2_last();
-
-	if (cpu_online(1))
-		tegra20_wake_cpu1_from_reset();
-
-	return true;
-}
-
-#ifdef CONFIG_SMP
-static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
-					 struct cpuidle_driver *drv,
-					 int index)
-{
-	cpu_suspend(0, tegra20_sleep_cpu_secondary_finish);
-
-	tegra20_cpu_clear_resettable();
-
-	return true;
-}
-#else
-static inline bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
-						struct cpuidle_driver *drv,
-						int index)
-{
-	return true;
-}
-#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())
-		WRITE_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;
-}
-#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;
-}
-
-int __init tegra20_cpuidle_init(void)
-{
-	return cpuidle_register(&tegra_idle_driver, cpu_possible_mask);
-}
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c
deleted file mode 100644
index c6128526877d..000000000000
--- a/arch/arm/mach-tegra/cpuidle-tegra30.c
+++ /dev/null
@@ -1,132 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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>
- */
-
-#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 "pm.h"
-#include "sleep.h"
-
-#ifdef CONFIG_PM_SLEEP
-static int tegra30_idle_lp2(struct cpuidle_device *dev,
-			    struct cpuidle_driver *drv,
-			    int index);
-#endif
-
-static struct cpuidle_driver tegra_idle_driver = {
-	.name = "tegra_idle",
-	.owner = THIS_MODULE,
-#ifdef CONFIG_PM_SLEEP
-	.state_count = 2,
-#else
-	.state_count = 1,
-#endif
-	.states = {
-		[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
-#ifdef CONFIG_PM_SLEEP
-		[1] = {
-			.enter			= tegra30_idle_lp2,
-			.exit_latency		= 2000,
-			.target_residency	= 2200,
-			.power_usage		= 0,
-			.flags			= CPUIDLE_FLAG_TIMER_STOP,
-			.name			= "powered-down",
-			.desc			= "CPU power gated",
-		},
-#endif
-	},
-};
-
-#ifdef CONFIG_PM_SLEEP
-static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
-					   struct cpuidle_driver *drv,
-					   int index)
-{
-	/* All CPUs entering LP2 is not working.
-	 * Don't let CPU0 enter LP2 when any secondary CPU is online.
-	 */
-	if (num_online_cpus() > 1 || !tegra_cpu_rail_off_ready()) {
-		cpu_do_idle();
-		return false;
-	}
-
-	tegra_idle_lp2_last();
-
-	return true;
-}
-
-#ifdef CONFIG_SMP
-static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
-					struct cpuidle_driver *drv,
-					int index)
-{
-	smp_wmb();
-
-	cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
-
-	return true;
-}
-#else
-static inline bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
-					       struct cpuidle_driver *drv,
-					       int index)
-{
-	return true;
-}
-#endif
-
-static int tegra30_idle_lp2(struct cpuidle_device *dev,
-			    struct cpuidle_driver *drv,
-			    int index)
-{
-	bool entered_lp2 = false;
-	bool last_cpu;
-
-	local_fiq_disable();
-
-	last_cpu = tegra_set_cpu_in_lp2();
-	cpu_pm_enter();
-
-	if (dev->cpu == 0) {
-		if (last_cpu)
-			entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv,
-								     index);
-		else
-			cpu_do_idle();
-	} else {
-		entered_lp2 = tegra30_cpu_core_power_down(dev, drv, index);
-	}
-
-	cpu_pm_exit();
-	tegra_clear_cpu_in_lp2();
-
-	local_fiq_enable();
-
-	smp_rmb();
-
-	return (entered_lp2) ? index : 0;
-}
-#endif
-
-int __init tegra30_cpuidle_init(void)
-{
-	return cpuidle_register(&tegra_idle_driver, NULL);
-}
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
deleted file mode 100644
index d565c44cfc93..000000000000
--- a/arch/arm/mach-tegra/cpuidle.c
+++ /dev/null
@@ -1,50 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * arch/arm/mach-tegra/cpuidle.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>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <soc/tegra/fuse.h>
-
-#include "cpuidle.h"
-
-void __init tegra_cpuidle_init(void)
-{
-	switch (tegra_get_chip_id()) {
-	case TEGRA20:
-		if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
-			tegra20_cpuidle_init();
-		break;
-	case TEGRA30:
-		if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC))
-			tegra30_cpuidle_init();
-		break;
-	case TEGRA114:
-	case TEGRA124:
-		if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
-		    IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
-			tegra114_cpuidle_init();
-		break;
-	}
-}
-
-void tegra_cpuidle_pcie_irqs_in_use(void)
-{
-	switch (tegra_get_chip_id()) {
-	case TEGRA20:
-		if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
-			tegra20_cpuidle_pcie_irqs_in_use();
-		break;
-	}
-}
diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h
deleted file mode 100644
index 4e1f459f5bd8..000000000000
--- a/arch/arm/mach-tegra/cpuidle.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
- */
-
-#ifndef __MACH_TEGRA_CPUIDLE_H
-#define __MACH_TEGRA_CPUIDLE_H
-
-#ifdef CONFIG_CPU_IDLE
-int tegra20_cpuidle_init(void);
-void tegra20_cpuidle_pcie_irqs_in_use(void);
-int tegra30_cpuidle_init(void);
-int tegra114_cpuidle_init(void);
-void tegra_cpuidle_init(void);
-void tegra_cpuidle_pcie_irqs_in_use(void);
-#else
-static inline void tegra_cpuidle_init(void) {}
-static inline void tegra_cpuidle_pcie_irqs_in_use(void) {}
-#endif
-
-#endif
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index ace7a390b5fe..22fca820f5c0 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -20,28 +20,10 @@
 
 #include "board.h"
 #include "iomap.h"
-#include "irq.h"
-
-#define SGI_MASK 0xFFFF
 
 #ifdef CONFIG_PM_SLEEP
 static void __iomem *tegra_gic_cpu_base;
-#endif
-
-bool tegra_pending_sgi(void)
-{
-	u32 pending_set;
-	void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
-
-	pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET);
 
-	if (pending_set & SGI_MASK)
-		return true;
-
-	return false;
-}
-
-#ifdef CONFIG_PM_SLEEP
 static int tegra_gic_notifier(struct notifier_block *self,
 			      unsigned long cmd, void *v)
 {
diff --git a/arch/arm/mach-tegra/irq.h b/arch/arm/mach-tegra/irq.h
deleted file mode 100644
index 7a94cf121448..000000000000
--- a/arch/arm/mach-tegra/irq.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
- */
-
-#ifndef __TEGRA_IRQ_H
-#define __TEGRA_IRQ_H
-
-bool tegra_pending_sgi(void);
-
-#endif
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 3cab81b82866..6aaacb5757e1 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -137,18 +137,11 @@ bool tegra_set_cpu_in_lp2(void)
 
 	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
 		last_cpu = true;
-	else if (tegra_get_chip_id() == TEGRA20 && phy_cpu_id == 1)
-		tegra20_cpu_set_resettable_soon();
 
 	spin_unlock(&tegra_lp2_lock);
 	return last_cpu;
 }
 
-int tegra_cpu_do_idle(void)
-{
-	return cpu_do_idle();
-}
-
 static int tegra_sleep_cpu(unsigned long v2p)
 {
 	/*
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
index 569151b3edc0..1e51a9b636eb 100644
--- a/arch/arm/mach-tegra/pm.h
+++ b/arch/arm/mach-tegra/pm.h
@@ -25,7 +25,6 @@ void tegra30_sleep_core_init(void);
 
 void tegra_clear_cpu_in_lp2(void);
 bool tegra_set_cpu_in_lp2(void);
-int tegra_cpu_do_idle(void);
 void tegra_idle_lp2_last(void);
 extern void (*tegra_tear_down_cpu)(void);
 
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 67b763fea005..df44828a34d3 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -183,17 +183,6 @@ after_errata:
 	bleq	__die				@ CPU not present (to OS)
 #endif
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-	/* Are we on Tegra20? */
-	cmp	r6, #TEGRA20
-	bne	1f
-	/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
-	mov	r0, #CPU_NOT_RESETTABLE
-	cmp	r10, #0
-	strbne	r0, [r12, #RESET_DATA(RESETTABLE_STATUS)]
-1:
-#endif
-
 	/* Waking up from LP1? */
 	ldr	r8, [r12, #RESET_DATA(MASK_LP1)]
 	tst	r8, r11				@ if in_lp1
diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h
index a4cfc08159f6..51265592cb1a 100644
--- a/arch/arm/mach-tegra/reset.h
+++ b/arch/arm/mach-tegra/reset.h
@@ -16,9 +16,8 @@
 #define TEGRA_RESET_STARTUP_SECONDARY	3
 #define TEGRA_RESET_STARTUP_LP2		4
 #define TEGRA_RESET_STARTUP_LP1		5
-#define TEGRA_RESET_RESETTABLE_STATUS	6
-#define TEGRA_RESET_TF_PRESENT		7
-#define TEGRA_RESET_DATA_SIZE		8
+#define TEGRA_RESET_TF_PRESENT		6
+#define TEGRA_RESET_DATA_SIZE		7
 
 #define RESET_DATA(x)	((TEGRA_RESET_##x)*4)
 
@@ -42,10 +41,6 @@ void __tegra_cpu_reset_handler_end(void);
 	(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
 	((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \
 	 (u32)__tegra_cpu_reset_handler_start)))
-#define tegra20_cpu1_resettable_status \
-	(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
-	((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_RESETTABLE_STATUS] - \
-	 (u32)__tegra_cpu_reset_handler_start)))
 #endif
 
 #define tegra_cpu_reset_handler_offset \
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index 9a89f30d53ca..6fb14f76235f 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -43,9 +43,6 @@
 #define APB_MISC_XM2CFGCPADCTRL2	0x8e4
 #define APB_MISC_XM2CFGDPADCTRL2	0x8e8
 
-#define __tegra20_cpu1_resettable_status_offset \
-	(__tegra_cpu_reset_handler_data_offset + RESET_DATA(RESETTABLE_STATUS))
-
 .macro pll_enable, rd, r_car_base, pll_base
 	ldr	\rd, [\r_car_base, #\pll_base]
 	tst	\rd, #(1 << 30)
@@ -64,21 +61,6 @@
 /*
  * tegra20_hotplug_shutdown(void)
  *
- * puts the current cpu in reset
- * should never return
- */
-ENTRY(tegra20_hotplug_shutdown)
-	/* Put this CPU down */
-	cpu_id	r0
-	bl	tegra20_cpu_shutdown
-	ret	lr			@ should never get here
-ENDPROC(tegra20_hotplug_shutdown)
-
-/*
- * tegra20_cpu_shutdown(int cpu)
- *
- * r0 is cpu to reset
- *
  * puts the specified CPU in wait-for-event mode on the flow controller
  * and puts the CPU in reset
  * can be called on the current cpu or another cpu
@@ -87,13 +69,10 @@ ENDPROC(tegra20_hotplug_shutdown)
  *
  * corrupts r0-r3, r12
  */
-ENTRY(tegra20_cpu_shutdown)
+ENTRY(tegra20_hotplug_shutdown)
+	cpu_id	r0
 	cmp	r0, #0
 	reteq	lr			@ must not be called for CPU 0
-	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r2, =__tegra20_cpu1_resettable_status_offset
-	mov	r12, #CPU_RESETTABLE
-	strb	r12, [r1, r2]
 
 	cpu_to_halt_reg r1, r0
 	ldr	r3, =TEGRA_FLOW_CTRL_VIRT
@@ -112,111 +91,10 @@ ENTRY(tegra20_cpu_shutdown)
 	cmp	r3, r0
 	beq	.
 	ret	lr
-ENDPROC(tegra20_cpu_shutdown)
+ENDPROC(tegra20_hotplug_shutdown)
 #endif
 
 #ifdef CONFIG_PM_SLEEP
-/*
- * tegra_pen_lock
- *
- * spinlock implementation with no atomic test-and-set and no coherence
- * using Peterson's algorithm on strongly-ordered registers
- * used to synchronize a cpu waking up from wfi with entering lp2 on idle
- *
- * The reference link of Peterson's algorithm:
- * http://en.wikipedia.org/wiki/Peterson's_algorithm
- *
- * SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm)
- * on cpu 0:
- * r2 = flag[0] (in SCRATCH38)
- * r3 = flag[1] (in SCRATCH39)
- * on cpu1:
- * r2 = flag[1] (in SCRATCH39)
- * r3 = flag[0] (in SCRATCH38)
- *
- * must be called with MMU on
- * corrupts r0-r3, r12
- */
-ENTRY(tegra_pen_lock)
-	mov32	r3, TEGRA_PMC_VIRT
-	cpu_id	r0
-	add	r1, r3, #PMC_SCRATCH37
-	cmp	r0, #0
-	addeq	r2, r3, #PMC_SCRATCH38
-	addeq	r3, r3, #PMC_SCRATCH39
-	addne	r2, r3, #PMC_SCRATCH39
-	addne	r3, r3, #PMC_SCRATCH38
-
-	mov	r12, #1
-	str	r12, [r2]		@ flag[cpu] = 1
-	dsb
-	str	r12, [r1]		@ !turn = cpu
-1:	dsb
-	ldr	r12, [r3]
-	cmp	r12, #1			@ flag[!cpu] == 1?
-	ldreq	r12, [r1]
-	cmpeq	r12, r0			@ !turn == cpu?
-	beq	1b			@ while !turn == cpu && flag[!cpu] == 1
-
-	ret	lr			@ locked
-ENDPROC(tegra_pen_lock)
-
-ENTRY(tegra_pen_unlock)
-	dsb
-	mov32	r3, TEGRA_PMC_VIRT
-	cpu_id	r0
-	cmp	r0, #0
-	addeq	r2, r3, #PMC_SCRATCH38
-	addne	r2, r3, #PMC_SCRATCH39
-	mov	r12, #0
-	str	r12, [r2]
-	ret     lr
-ENDPROC(tegra_pen_unlock)
-
-/*
- * tegra20_cpu_clear_resettable(void)
- *
- * Called to clear the "resettable soon" flag in IRAM variable when
- * it is expected that the secondary CPU will be idle soon.
- */
-ENTRY(tegra20_cpu_clear_resettable)
-	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r2, =__tegra20_cpu1_resettable_status_offset
-	mov	r12, #CPU_NOT_RESETTABLE
-	strb	r12, [r1, r2]
-	ret	lr
-ENDPROC(tegra20_cpu_clear_resettable)
-
-/*
- * tegra20_cpu_set_resettable_soon(void)
- *
- * Called to set the "resettable soon" flag in IRAM variable when
- * it is expected that the secondary CPU will be idle soon.
- */
-ENTRY(tegra20_cpu_set_resettable_soon)
-	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r2, =__tegra20_cpu1_resettable_status_offset
-	mov	r12, #CPU_RESETTABLE_SOON
-	strb	r12, [r1, r2]
-	ret	lr
-ENDPROC(tegra20_cpu_set_resettable_soon)
-
-/*
- * tegra20_cpu_is_resettable_soon(void)
- *
- * Returns true if the "resettable soon" flag in IRAM variable has been
- * set because it is expected that the secondary CPU will be idle soon.
- */
-ENTRY(tegra20_cpu_is_resettable_soon)
-	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r2, =__tegra20_cpu1_resettable_status_offset
-	ldrb	r12, [r1, r2]
-	cmp	r12, #CPU_RESETTABLE_SOON
-	moveq	r0, #1
-	movne	r0, #0
-	ret	lr
-ENDPROC(tegra20_cpu_is_resettable_soon)
-
 /*
  * tegra20_sleep_core_finish(unsigned long v2p)
  *
@@ -242,68 +120,6 @@ ENTRY(tegra20_sleep_core_finish)
 	ret	r3
 ENDPROC(tegra20_sleep_core_finish)
 
-/*
- * tegra20_sleep_cpu_secondary_finish(unsigned long v2p)
- *
- * Enters WFI on secondary CPU by exiting coherency.
- */
-ENTRY(tegra20_sleep_cpu_secondary_finish)
-	stmfd	sp!, {r4-r11, lr}
-
-	mrc	p15, 0, r11, c1, c0, 1  @ save actlr before exiting coherency
-
-	/* Flush and disable the L1 data cache */
-	mov	r0, #TEGRA_FLUSH_CACHE_LOUIS
-	bl	tegra_disable_clean_inv_dcache
-
-	mov32	r0, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r4, =__tegra20_cpu1_resettable_status_offset
-	mov	r3, #CPU_RESETTABLE
-	strb	r3, [r0, r4]
-
-	bl	tegra_cpu_do_idle
-
-	/*
-	 * cpu may be reset while in wfi, which will return through
-	 * tegra_resume to cpu_resume
-	 * or interrupt may wake wfi, which will return here
-	 * cpu state is unchanged - MMU is on, cache is on, coherency
-	 * is off, and the data cache is off
-	 *
-	 * r11 contains the original actlr
-	 */
-
-	bl	tegra_pen_lock
-
-	mov32	r0, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r4, =__tegra20_cpu1_resettable_status_offset
-	mov	r3, #CPU_NOT_RESETTABLE
-	strb	r3, [r0, r4]
-
-	bl	tegra_pen_unlock
-
-	/* Re-enable the data cache */
-	mrc	p15, 0, r10, c1, c0, 0
-	orr	r10, r10, #CR_C
-	mcr	p15, 0, r10, c1, c0, 0
-	isb
-
-	mcr	p15, 0, r11, c1, c0, 1	@ reenable coherency
-
-	/* Invalidate the TLBs & BTAC */
-	mov	r1, #0
-	mcr	p15, 0, r1, c8, c3, 0	@ invalidate shared TLBs
-	mcr	p15, 0, r1, c7, c1, 6	@ invalidate shared BTAC
-	dsb
-	isb
-
-	/* the cpu was running with coherency disabled,
-	 * caches may be out of date */
-	bl	v7_flush_kern_cache_louis
-
-	ldmfd	sp!, {r4 - r11, pc}
-ENDPROC(tegra20_sleep_cpu_secondary_finish)
-
 /*
  * tegra20_tear_down_cpu
  *
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 78ef32a907c8..d219872b7546 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -114,8 +114,6 @@
 .endm
 
 #else
-void tegra_pen_lock(void);
-void tegra_pen_unlock(void);
 void tegra_resume(void);
 int tegra_sleep_cpu_finish(unsigned long);
 void tegra_disable_clean_inv_dcache(u32 flag);
@@ -125,16 +123,6 @@ void tegra20_hotplug_shutdown(void);
 void tegra30_hotplug_shutdown(void);
 #endif
 
-void tegra20_cpu_shutdown(int cpu);
-int tegra20_cpu_is_resettable_soon(void);
-void tegra20_cpu_clear_resettable(void);
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-void tegra20_cpu_set_resettable_soon(void);
-#else
-static inline void tegra20_cpu_set_resettable_soon(void) {}
-#endif
-
-int tegra20_sleep_cpu_secondary_finish(unsigned long);
 void tegra20_tear_down_cpu(void);
 int tegra30_sleep_cpu_secondary_finish(unsigned long);
 void tegra30_tear_down_cpu(void);
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index e512e606eabd..d9237769a37c 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -40,9 +40,7 @@
 
 #include "board.h"
 #include "common.h"
-#include "cpuidle.h"
 #include "iomap.h"
-#include "irq.h"
 #include "pm.h"
 #include "reset.h"
 #include "sleep.h"
@@ -86,7 +84,6 @@ static void __init tegra_dt_init(void)
 static void __init tegra_dt_init_late(void)
 {
 	tegra_init_suspend();
-	tegra_cpuidle_init();
 
 	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
 	    of_machine_is_compatible("compal,paz00"))
diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index c8ef05d6b8c7..d98c69efb7e0 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -6,7 +6,6 @@ if ARM
 
 config ARCH_TEGRA_2x_SOC
 	bool "Enable support for Tegra20 family"
-	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
 	select ARM_ERRATA_720789
 	select ARM_ERRATA_754327 if SMP
 	select ARM_ERRATA_764369 if SMP
diff --git a/include/soc/tegra/cpuidle.h b/include/soc/tegra/cpuidle.h
index 029ba1f4b2cc..f758808342b6 100644
--- a/include/soc/tegra/cpuidle.h
+++ b/include/soc/tegra/cpuidle.h
@@ -6,12 +6,8 @@
 #ifndef __SOC_TEGRA_CPUIDLE_H__
 #define __SOC_TEGRA_CPUIDLE_H__
 
-#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_TEGRA) && defined(CONFIG_CPU_IDLE)
-void tegra_cpuidle_pcie_irqs_in_use(void);
-#else
 static inline void tegra_cpuidle_pcie_irqs_in_use(void)
 {
 }
-#endif
 
 #endif /* __SOC_TEGRA_CPUIDLE_H__ */
-- 
2.22.0

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
@ 2019-07-11  3:13   ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

Remove the old drivers to replace them cleanly with a new one later on.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/Makefile           |  13 --
 arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
 arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
 arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
 arch/arm/mach-tegra/cpuidle.c          |  50 ------
 arch/arm/mach-tegra/cpuidle.h          |  21 ---
 arch/arm/mach-tegra/irq.c              |  18 ---
 arch/arm/mach-tegra/irq.h              |  11 --
 arch/arm/mach-tegra/pm.c               |   7 -
 arch/arm/mach-tegra/pm.h               |   1 -
 arch/arm/mach-tegra/reset-handler.S    |  11 --
 arch/arm/mach-tegra/reset.h            |   9 +-
 arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
 arch/arm/mach-tegra/sleep.h            |  12 --
 arch/arm/mach-tegra/tegra.c            |   3 -
 drivers/soc/tegra/Kconfig              |   1 -
 include/soc/tegra/cpuidle.h            |   4 -
 17 files changed, 5 insertions(+), 779 deletions(-)
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle.c
 delete mode 100644 arch/arm/mach-tegra/cpuidle.h
 delete mode 100644 arch/arm/mach-tegra/irq.h

diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 6c1dff2eccc2..5d93a0b36866 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -8,29 +8,16 @@ obj-y					+= reset.o
 obj-y					+= reset-handler.o
 obj-y					+= sleep.o
 obj-y					+= tegra.o
-obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= sleep-tegra20.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pm-tegra20.o
-ifeq ($(CONFIG_CPU_IDLE),y)
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= cpuidle-tegra20.o
-endif
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= pm-tegra30.o
-ifeq ($(CONFIG_CPU_IDLE),y)
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= cpuidle-tegra30.o
-endif
 obj-$(CONFIG_SMP)			+= platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
 
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= sleep-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= pm-tegra30.o
-ifeq ($(CONFIG_CPU_IDLE),y)
-obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= cpuidle-tegra114.o
-endif
 obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= sleep-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= pm-tegra30.o
-ifeq ($(CONFIG_CPU_IDLE),y)
-obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= cpuidle-tegra114.o
-endif
 
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= board-paz00.o
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
deleted file mode 100644
index 5118f777fd66..000000000000
--- a/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
- */
-
-#include <asm/firmware.h>
-#include <linux/tick.h>
-#include <linux/cpuidle.h>
-#include <linux/cpu_pm.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/firmware/trusted_foundations.h>
-
-#include <asm/cpuidle.h>
-#include <asm/smp_plat.h>
-#include <asm/suspend.h>
-#include <asm/psci.h>
-
-#include "cpuidle.h"
-#include "pm.h"
-#include "sleep.h"
-
-#ifdef CONFIG_PM_SLEEP
-#define TEGRA114_MAX_STATES 2
-#else
-#define TEGRA114_MAX_STATES 1
-#endif
-
-#ifdef CONFIG_PM_SLEEP
-static int tegra114_idle_power_down(struct cpuidle_device *dev,
-				    struct cpuidle_driver *drv,
-				    int index)
-{
-	local_fiq_disable();
-
-	tegra_set_cpu_in_lp2();
-	cpu_pm_enter();
-
-	call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
-
-	/* Do suspend by ourselves if the firmware does not implement it */
-	if (call_firmware_op(do_idle, 0) == -ENOSYS)
-		cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
-
-	cpu_pm_exit();
-	tegra_clear_cpu_in_lp2();
-
-	local_fiq_enable();
-
-	return index;
-}
-
-static void tegra114_idle_enter_s2idle(struct cpuidle_device *dev,
-				       struct cpuidle_driver *drv,
-				       int index)
-{
-       tegra114_idle_power_down(dev, drv, index);
-}
-#endif
-
-static struct cpuidle_driver tegra_idle_driver = {
-	.name = "tegra_idle",
-	.owner = THIS_MODULE,
-	.state_count = TEGRA114_MAX_STATES,
-	.states = {
-		[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
-#ifdef CONFIG_PM_SLEEP
-		[1] = {
-			.enter			= tegra114_idle_power_down,
-			.enter_s2idle		= tegra114_idle_enter_s2idle,
-			.exit_latency		= 500,
-			.target_residency	= 1000,
-			.flags			= CPUIDLE_FLAG_TIMER_STOP,
-			.power_usage		= 0,
-			.name			= "powered-down",
-			.desc			= "CPU power gated",
-		},
-#endif
-	},
-};
-
-int __init tegra114_cpuidle_init(void)
-{
-	if (!psci_smp_available())
-		return cpuidle_register(&tegra_idle_driver, NULL);
-
-	return 0;
-}
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
deleted file mode 100644
index 2447427cb4a8..000000000000
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ /dev/null
@@ -1,212 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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>
- */
-
-#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 <soc/tegra/flowctrl.h>
-
-#include <asm/cpuidle.h>
-#include <asm/smp_plat.h>
-#include <asm/suspend.h>
-
-#include "cpuidle.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 |
-			                    CPUIDLE_FLAG_TIMER_STOP,
-			.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;
-}
-
-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();
-}
-
-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;
-}
-#else
-static inline void tegra20_wake_cpu1_from_reset(void)
-{
-}
-
-static inline int tegra20_reset_cpu_1(void)
-{
-	return 0;
-}
-#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;
-
-	tegra_idle_lp2_last();
-
-	if (cpu_online(1))
-		tegra20_wake_cpu1_from_reset();
-
-	return true;
-}
-
-#ifdef CONFIG_SMP
-static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
-					 struct cpuidle_driver *drv,
-					 int index)
-{
-	cpu_suspend(0, tegra20_sleep_cpu_secondary_finish);
-
-	tegra20_cpu_clear_resettable();
-
-	return true;
-}
-#else
-static inline bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
-						struct cpuidle_driver *drv,
-						int index)
-{
-	return true;
-}
-#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())
-		WRITE_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;
-}
-#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;
-}
-
-int __init tegra20_cpuidle_init(void)
-{
-	return cpuidle_register(&tegra_idle_driver, cpu_possible_mask);
-}
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c
deleted file mode 100644
index c6128526877d..000000000000
--- a/arch/arm/mach-tegra/cpuidle-tegra30.c
+++ /dev/null
@@ -1,132 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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>
- */
-
-#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 "pm.h"
-#include "sleep.h"
-
-#ifdef CONFIG_PM_SLEEP
-static int tegra30_idle_lp2(struct cpuidle_device *dev,
-			    struct cpuidle_driver *drv,
-			    int index);
-#endif
-
-static struct cpuidle_driver tegra_idle_driver = {
-	.name = "tegra_idle",
-	.owner = THIS_MODULE,
-#ifdef CONFIG_PM_SLEEP
-	.state_count = 2,
-#else
-	.state_count = 1,
-#endif
-	.states = {
-		[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
-#ifdef CONFIG_PM_SLEEP
-		[1] = {
-			.enter			= tegra30_idle_lp2,
-			.exit_latency		= 2000,
-			.target_residency	= 2200,
-			.power_usage		= 0,
-			.flags			= CPUIDLE_FLAG_TIMER_STOP,
-			.name			= "powered-down",
-			.desc			= "CPU power gated",
-		},
-#endif
-	},
-};
-
-#ifdef CONFIG_PM_SLEEP
-static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
-					   struct cpuidle_driver *drv,
-					   int index)
-{
-	/* All CPUs entering LP2 is not working.
-	 * Don't let CPU0 enter LP2 when any secondary CPU is online.
-	 */
-	if (num_online_cpus() > 1 || !tegra_cpu_rail_off_ready()) {
-		cpu_do_idle();
-		return false;
-	}
-
-	tegra_idle_lp2_last();
-
-	return true;
-}
-
-#ifdef CONFIG_SMP
-static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
-					struct cpuidle_driver *drv,
-					int index)
-{
-	smp_wmb();
-
-	cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
-
-	return true;
-}
-#else
-static inline bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
-					       struct cpuidle_driver *drv,
-					       int index)
-{
-	return true;
-}
-#endif
-
-static int tegra30_idle_lp2(struct cpuidle_device *dev,
-			    struct cpuidle_driver *drv,
-			    int index)
-{
-	bool entered_lp2 = false;
-	bool last_cpu;
-
-	local_fiq_disable();
-
-	last_cpu = tegra_set_cpu_in_lp2();
-	cpu_pm_enter();
-
-	if (dev->cpu == 0) {
-		if (last_cpu)
-			entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv,
-								     index);
-		else
-			cpu_do_idle();
-	} else {
-		entered_lp2 = tegra30_cpu_core_power_down(dev, drv, index);
-	}
-
-	cpu_pm_exit();
-	tegra_clear_cpu_in_lp2();
-
-	local_fiq_enable();
-
-	smp_rmb();
-
-	return (entered_lp2) ? index : 0;
-}
-#endif
-
-int __init tegra30_cpuidle_init(void)
-{
-	return cpuidle_register(&tegra_idle_driver, NULL);
-}
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
deleted file mode 100644
index d565c44cfc93..000000000000
--- a/arch/arm/mach-tegra/cpuidle.c
+++ /dev/null
@@ -1,50 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * arch/arm/mach-tegra/cpuidle.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>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <soc/tegra/fuse.h>
-
-#include "cpuidle.h"
-
-void __init tegra_cpuidle_init(void)
-{
-	switch (tegra_get_chip_id()) {
-	case TEGRA20:
-		if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
-			tegra20_cpuidle_init();
-		break;
-	case TEGRA30:
-		if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC))
-			tegra30_cpuidle_init();
-		break;
-	case TEGRA114:
-	case TEGRA124:
-		if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) ||
-		    IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC))
-			tegra114_cpuidle_init();
-		break;
-	}
-}
-
-void tegra_cpuidle_pcie_irqs_in_use(void)
-{
-	switch (tegra_get_chip_id()) {
-	case TEGRA20:
-		if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
-			tegra20_cpuidle_pcie_irqs_in_use();
-		break;
-	}
-}
diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h
deleted file mode 100644
index 4e1f459f5bd8..000000000000
--- a/arch/arm/mach-tegra/cpuidle.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
- */
-
-#ifndef __MACH_TEGRA_CPUIDLE_H
-#define __MACH_TEGRA_CPUIDLE_H
-
-#ifdef CONFIG_CPU_IDLE
-int tegra20_cpuidle_init(void);
-void tegra20_cpuidle_pcie_irqs_in_use(void);
-int tegra30_cpuidle_init(void);
-int tegra114_cpuidle_init(void);
-void tegra_cpuidle_init(void);
-void tegra_cpuidle_pcie_irqs_in_use(void);
-#else
-static inline void tegra_cpuidle_init(void) {}
-static inline void tegra_cpuidle_pcie_irqs_in_use(void) {}
-#endif
-
-#endif
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index ace7a390b5fe..22fca820f5c0 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -20,28 +20,10 @@
 
 #include "board.h"
 #include "iomap.h"
-#include "irq.h"
-
-#define SGI_MASK 0xFFFF
 
 #ifdef CONFIG_PM_SLEEP
 static void __iomem *tegra_gic_cpu_base;
-#endif
-
-bool tegra_pending_sgi(void)
-{
-	u32 pending_set;
-	void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
-
-	pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET);
 
-	if (pending_set & SGI_MASK)
-		return true;
-
-	return false;
-}
-
-#ifdef CONFIG_PM_SLEEP
 static int tegra_gic_notifier(struct notifier_block *self,
 			      unsigned long cmd, void *v)
 {
diff --git a/arch/arm/mach-tegra/irq.h b/arch/arm/mach-tegra/irq.h
deleted file mode 100644
index 7a94cf121448..000000000000
--- a/arch/arm/mach-tegra/irq.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
- */
-
-#ifndef __TEGRA_IRQ_H
-#define __TEGRA_IRQ_H
-
-bool tegra_pending_sgi(void);
-
-#endif
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 3cab81b82866..6aaacb5757e1 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -137,18 +137,11 @@ bool tegra_set_cpu_in_lp2(void)
 
 	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
 		last_cpu = true;
-	else if (tegra_get_chip_id() == TEGRA20 && phy_cpu_id == 1)
-		tegra20_cpu_set_resettable_soon();
 
 	spin_unlock(&tegra_lp2_lock);
 	return last_cpu;
 }
 
-int tegra_cpu_do_idle(void)
-{
-	return cpu_do_idle();
-}
-
 static int tegra_sleep_cpu(unsigned long v2p)
 {
 	/*
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
index 569151b3edc0..1e51a9b636eb 100644
--- a/arch/arm/mach-tegra/pm.h
+++ b/arch/arm/mach-tegra/pm.h
@@ -25,7 +25,6 @@ void tegra30_sleep_core_init(void);
 
 void tegra_clear_cpu_in_lp2(void);
 bool tegra_set_cpu_in_lp2(void);
-int tegra_cpu_do_idle(void);
 void tegra_idle_lp2_last(void);
 extern void (*tegra_tear_down_cpu)(void);
 
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S
index 67b763fea005..df44828a34d3 100644
--- a/arch/arm/mach-tegra/reset-handler.S
+++ b/arch/arm/mach-tegra/reset-handler.S
@@ -183,17 +183,6 @@ after_errata:
 	bleq	__die				@ CPU not present (to OS)
 #endif
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-	/* Are we on Tegra20? */
-	cmp	r6, #TEGRA20
-	bne	1f
-	/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
-	mov	r0, #CPU_NOT_RESETTABLE
-	cmp	r10, #0
-	strbne	r0, [r12, #RESET_DATA(RESETTABLE_STATUS)]
-1:
-#endif
-
 	/* Waking up from LP1? */
 	ldr	r8, [r12, #RESET_DATA(MASK_LP1)]
 	tst	r8, r11				@ if in_lp1
diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h
index a4cfc08159f6..51265592cb1a 100644
--- a/arch/arm/mach-tegra/reset.h
+++ b/arch/arm/mach-tegra/reset.h
@@ -16,9 +16,8 @@
 #define TEGRA_RESET_STARTUP_SECONDARY	3
 #define TEGRA_RESET_STARTUP_LP2		4
 #define TEGRA_RESET_STARTUP_LP1		5
-#define TEGRA_RESET_RESETTABLE_STATUS	6
-#define TEGRA_RESET_TF_PRESENT		7
-#define TEGRA_RESET_DATA_SIZE		8
+#define TEGRA_RESET_TF_PRESENT		6
+#define TEGRA_RESET_DATA_SIZE		7
 
 #define RESET_DATA(x)	((TEGRA_RESET_##x)*4)
 
@@ -42,10 +41,6 @@ void __tegra_cpu_reset_handler_end(void);
 	(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
 	((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \
 	 (u32)__tegra_cpu_reset_handler_start)))
-#define tegra20_cpu1_resettable_status \
-	(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
-	((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_RESETTABLE_STATUS] - \
-	 (u32)__tegra_cpu_reset_handler_start)))
 #endif
 
 #define tegra_cpu_reset_handler_offset \
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index 9a89f30d53ca..6fb14f76235f 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -43,9 +43,6 @@
 #define APB_MISC_XM2CFGCPADCTRL2	0x8e4
 #define APB_MISC_XM2CFGDPADCTRL2	0x8e8
 
-#define __tegra20_cpu1_resettable_status_offset \
-	(__tegra_cpu_reset_handler_data_offset + RESET_DATA(RESETTABLE_STATUS))
-
 .macro pll_enable, rd, r_car_base, pll_base
 	ldr	\rd, [\r_car_base, #\pll_base]
 	tst	\rd, #(1 << 30)
@@ -64,21 +61,6 @@
 /*
  * tegra20_hotplug_shutdown(void)
  *
- * puts the current cpu in reset
- * should never return
- */
-ENTRY(tegra20_hotplug_shutdown)
-	/* Put this CPU down */
-	cpu_id	r0
-	bl	tegra20_cpu_shutdown
-	ret	lr			@ should never get here
-ENDPROC(tegra20_hotplug_shutdown)
-
-/*
- * tegra20_cpu_shutdown(int cpu)
- *
- * r0 is cpu to reset
- *
  * puts the specified CPU in wait-for-event mode on the flow controller
  * and puts the CPU in reset
  * can be called on the current cpu or another cpu
@@ -87,13 +69,10 @@ ENDPROC(tegra20_hotplug_shutdown)
  *
  * corrupts r0-r3, r12
  */
-ENTRY(tegra20_cpu_shutdown)
+ENTRY(tegra20_hotplug_shutdown)
+	cpu_id	r0
 	cmp	r0, #0
 	reteq	lr			@ must not be called for CPU 0
-	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r2, =__tegra20_cpu1_resettable_status_offset
-	mov	r12, #CPU_RESETTABLE
-	strb	r12, [r1, r2]
 
 	cpu_to_halt_reg r1, r0
 	ldr	r3, =TEGRA_FLOW_CTRL_VIRT
@@ -112,111 +91,10 @@ ENTRY(tegra20_cpu_shutdown)
 	cmp	r3, r0
 	beq	.
 	ret	lr
-ENDPROC(tegra20_cpu_shutdown)
+ENDPROC(tegra20_hotplug_shutdown)
 #endif
 
 #ifdef CONFIG_PM_SLEEP
-/*
- * tegra_pen_lock
- *
- * spinlock implementation with no atomic test-and-set and no coherence
- * using Peterson's algorithm on strongly-ordered registers
- * used to synchronize a cpu waking up from wfi with entering lp2 on idle
- *
- * The reference link of Peterson's algorithm:
- * http://en.wikipedia.org/wiki/Peterson's_algorithm
- *
- * SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm)
- * on cpu 0:
- * r2 = flag[0] (in SCRATCH38)
- * r3 = flag[1] (in SCRATCH39)
- * on cpu1:
- * r2 = flag[1] (in SCRATCH39)
- * r3 = flag[0] (in SCRATCH38)
- *
- * must be called with MMU on
- * corrupts r0-r3, r12
- */
-ENTRY(tegra_pen_lock)
-	mov32	r3, TEGRA_PMC_VIRT
-	cpu_id	r0
-	add	r1, r3, #PMC_SCRATCH37
-	cmp	r0, #0
-	addeq	r2, r3, #PMC_SCRATCH38
-	addeq	r3, r3, #PMC_SCRATCH39
-	addne	r2, r3, #PMC_SCRATCH39
-	addne	r3, r3, #PMC_SCRATCH38
-
-	mov	r12, #1
-	str	r12, [r2]		@ flag[cpu] = 1
-	dsb
-	str	r12, [r1]		@ !turn = cpu
-1:	dsb
-	ldr	r12, [r3]
-	cmp	r12, #1			@ flag[!cpu] == 1?
-	ldreq	r12, [r1]
-	cmpeq	r12, r0			@ !turn == cpu?
-	beq	1b			@ while !turn == cpu && flag[!cpu] == 1
-
-	ret	lr			@ locked
-ENDPROC(tegra_pen_lock)
-
-ENTRY(tegra_pen_unlock)
-	dsb
-	mov32	r3, TEGRA_PMC_VIRT
-	cpu_id	r0
-	cmp	r0, #0
-	addeq	r2, r3, #PMC_SCRATCH38
-	addne	r2, r3, #PMC_SCRATCH39
-	mov	r12, #0
-	str	r12, [r2]
-	ret     lr
-ENDPROC(tegra_pen_unlock)
-
-/*
- * tegra20_cpu_clear_resettable(void)
- *
- * Called to clear the "resettable soon" flag in IRAM variable when
- * it is expected that the secondary CPU will be idle soon.
- */
-ENTRY(tegra20_cpu_clear_resettable)
-	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r2, =__tegra20_cpu1_resettable_status_offset
-	mov	r12, #CPU_NOT_RESETTABLE
-	strb	r12, [r1, r2]
-	ret	lr
-ENDPROC(tegra20_cpu_clear_resettable)
-
-/*
- * tegra20_cpu_set_resettable_soon(void)
- *
- * Called to set the "resettable soon" flag in IRAM variable when
- * it is expected that the secondary CPU will be idle soon.
- */
-ENTRY(tegra20_cpu_set_resettable_soon)
-	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r2, =__tegra20_cpu1_resettable_status_offset
-	mov	r12, #CPU_RESETTABLE_SOON
-	strb	r12, [r1, r2]
-	ret	lr
-ENDPROC(tegra20_cpu_set_resettable_soon)
-
-/*
- * tegra20_cpu_is_resettable_soon(void)
- *
- * Returns true if the "resettable soon" flag in IRAM variable has been
- * set because it is expected that the secondary CPU will be idle soon.
- */
-ENTRY(tegra20_cpu_is_resettable_soon)
-	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r2, =__tegra20_cpu1_resettable_status_offset
-	ldrb	r12, [r1, r2]
-	cmp	r12, #CPU_RESETTABLE_SOON
-	moveq	r0, #1
-	movne	r0, #0
-	ret	lr
-ENDPROC(tegra20_cpu_is_resettable_soon)
-
 /*
  * tegra20_sleep_core_finish(unsigned long v2p)
  *
@@ -242,68 +120,6 @@ ENTRY(tegra20_sleep_core_finish)
 	ret	r3
 ENDPROC(tegra20_sleep_core_finish)
 
-/*
- * tegra20_sleep_cpu_secondary_finish(unsigned long v2p)
- *
- * Enters WFI on secondary CPU by exiting coherency.
- */
-ENTRY(tegra20_sleep_cpu_secondary_finish)
-	stmfd	sp!, {r4-r11, lr}
-
-	mrc	p15, 0, r11, c1, c0, 1  @ save actlr before exiting coherency
-
-	/* Flush and disable the L1 data cache */
-	mov	r0, #TEGRA_FLUSH_CACHE_LOUIS
-	bl	tegra_disable_clean_inv_dcache
-
-	mov32	r0, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r4, =__tegra20_cpu1_resettable_status_offset
-	mov	r3, #CPU_RESETTABLE
-	strb	r3, [r0, r4]
-
-	bl	tegra_cpu_do_idle
-
-	/*
-	 * cpu may be reset while in wfi, which will return through
-	 * tegra_resume to cpu_resume
-	 * or interrupt may wake wfi, which will return here
-	 * cpu state is unchanged - MMU is on, cache is on, coherency
-	 * is off, and the data cache is off
-	 *
-	 * r11 contains the original actlr
-	 */
-
-	bl	tegra_pen_lock
-
-	mov32	r0, TEGRA_IRAM_RESET_BASE_VIRT
-	ldr	r4, =__tegra20_cpu1_resettable_status_offset
-	mov	r3, #CPU_NOT_RESETTABLE
-	strb	r3, [r0, r4]
-
-	bl	tegra_pen_unlock
-
-	/* Re-enable the data cache */
-	mrc	p15, 0, r10, c1, c0, 0
-	orr	r10, r10, #CR_C
-	mcr	p15, 0, r10, c1, c0, 0
-	isb
-
-	mcr	p15, 0, r11, c1, c0, 1	@ reenable coherency
-
-	/* Invalidate the TLBs & BTAC */
-	mov	r1, #0
-	mcr	p15, 0, r1, c8, c3, 0	@ invalidate shared TLBs
-	mcr	p15, 0, r1, c7, c1, 6	@ invalidate shared BTAC
-	dsb
-	isb
-
-	/* the cpu was running with coherency disabled,
-	 * caches may be out of date */
-	bl	v7_flush_kern_cache_louis
-
-	ldmfd	sp!, {r4 - r11, pc}
-ENDPROC(tegra20_sleep_cpu_secondary_finish)
-
 /*
  * tegra20_tear_down_cpu
  *
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 78ef32a907c8..d219872b7546 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -114,8 +114,6 @@
 .endm
 
 #else
-void tegra_pen_lock(void);
-void tegra_pen_unlock(void);
 void tegra_resume(void);
 int tegra_sleep_cpu_finish(unsigned long);
 void tegra_disable_clean_inv_dcache(u32 flag);
@@ -125,16 +123,6 @@ void tegra20_hotplug_shutdown(void);
 void tegra30_hotplug_shutdown(void);
 #endif
 
-void tegra20_cpu_shutdown(int cpu);
-int tegra20_cpu_is_resettable_soon(void);
-void tegra20_cpu_clear_resettable(void);
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-void tegra20_cpu_set_resettable_soon(void);
-#else
-static inline void tegra20_cpu_set_resettable_soon(void) {}
-#endif
-
-int tegra20_sleep_cpu_secondary_finish(unsigned long);
 void tegra20_tear_down_cpu(void);
 int tegra30_sleep_cpu_secondary_finish(unsigned long);
 void tegra30_tear_down_cpu(void);
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index e512e606eabd..d9237769a37c 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -40,9 +40,7 @@
 
 #include "board.h"
 #include "common.h"
-#include "cpuidle.h"
 #include "iomap.h"
-#include "irq.h"
 #include "pm.h"
 #include "reset.h"
 #include "sleep.h"
@@ -86,7 +84,6 @@ static void __init tegra_dt_init(void)
 static void __init tegra_dt_init_late(void)
 {
 	tegra_init_suspend();
-	tegra_cpuidle_init();
 
 	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
 	    of_machine_is_compatible("compal,paz00"))
diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index c8ef05d6b8c7..d98c69efb7e0 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -6,7 +6,6 @@ if ARM
 
 config ARCH_TEGRA_2x_SOC
 	bool "Enable support for Tegra20 family"
-	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
 	select ARM_ERRATA_720789
 	select ARM_ERRATA_754327 if SMP
 	select ARM_ERRATA_764369 if SMP
diff --git a/include/soc/tegra/cpuidle.h b/include/soc/tegra/cpuidle.h
index 029ba1f4b2cc..f758808342b6 100644
--- a/include/soc/tegra/cpuidle.h
+++ b/include/soc/tegra/cpuidle.h
@@ -6,12 +6,8 @@
 #ifndef __SOC_TEGRA_CPUIDLE_H__
 #define __SOC_TEGRA_CPUIDLE_H__
 
-#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_TEGRA) && defined(CONFIG_CPU_IDLE)
-void tegra_cpuidle_pcie_irqs_in_use(void);
-#else
 static inline void tegra_cpuidle_pcie_irqs_in_use(void)
 {
 }
-#endif
 
 #endif /* __SOC_TEGRA_CPUIDLE_H__ */
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 2/6] ARM: tegra: Expose functions required for cpuidle driver
  2019-07-11  3:13 ` Dmitry Osipenko
@ 2019-07-11  3:13   ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

The upcoming unified CPUIDLE driver will be added to the drivers/cpuidle/
directory and it will require all these Tegra PM-core functions.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/Makefile  |  2 +-
 arch/arm/mach-tegra/platsmp.c |  2 --
 arch/arm/mach-tegra/pm.c      | 16 +++++++---------
 arch/arm/mach-tegra/pm.h      |  3 ---
 arch/arm/mach-tegra/sleep.h   |  1 -
 include/linux/clk/tegra.h     | 13 +++++++++++++
 include/soc/tegra/pm.h        | 28 ++++++++++++++++++++++++++++
 7 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 5d93a0b36866..27bd5d9865e3 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pm-tegra20.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= pm-tegra30.o
 obj-$(CONFIG_SMP)			+= platsmp.o
-obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
+obj-y					+= hotplug.o
 
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= sleep-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= pm-tegra30.o
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index e6911a14c096..c8a63719a143 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -183,8 +183,6 @@ const struct smp_operations tegra_smp_ops __initconst = {
 	.smp_prepare_cpus	= tegra_smp_prepare_cpus,
 	.smp_secondary_init	= tegra_secondary_init,
 	.smp_boot_secondary	= tegra_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
 	.cpu_kill		= tegra_cpu_kill,
 	.cpu_die		= tegra_cpu_die,
-#endif
 };
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 6aaacb5757e1..f9c9bce9e15d 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void)
 	spin_unlock(&tegra_lp2_lock);
 }
 
-bool tegra_set_cpu_in_lp2(void)
+void tegra_set_cpu_in_lp2(void)
 {
 	int phy_cpu_id = cpu_logical_map(smp_processor_id());
-	bool last_cpu = false;
-	cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
 	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
 
 	spin_lock(&tegra_lp2_lock);
@@ -135,11 +133,7 @@ bool tegra_set_cpu_in_lp2(void)
 	BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
 	*cpu_in_lp2 |= BIT(phy_cpu_id);
 
-	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
-		last_cpu = true;
-
 	spin_unlock(&tegra_lp2_lock);
-	return last_cpu;
 }
 
 static int tegra_sleep_cpu(unsigned long v2p)
@@ -195,14 +189,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
 	tegra_pmc_enter_suspend_mode(mode);
 }
 
-void tegra_idle_lp2_last(void)
+int tegra_idle_lp2_last(void)
 {
+	int err;
+
 	tegra_pm_set(TEGRA_SUSPEND_LP2);
 
 	cpu_cluster_pm_enter();
 	suspend_cpu_complex();
 
-	cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
+	err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
 
 	/*
 	 * Resume L2 cache if it wasn't re-enabled early during resume,
@@ -214,6 +210,8 @@ void tegra_idle_lp2_last(void)
 
 	restore_cpu_complex();
 	cpu_cluster_pm_exit();
+
+	return err;
 }
 
 enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
index 1e51a9b636eb..81525f5f4a44 100644
--- a/arch/arm/mach-tegra/pm.h
+++ b/arch/arm/mach-tegra/pm.h
@@ -23,9 +23,6 @@ void tegra20_sleep_core_init(void);
 void tegra30_lp1_iram_hook(void);
 void tegra30_sleep_core_init(void);
 
-void tegra_clear_cpu_in_lp2(void);
-bool tegra_set_cpu_in_lp2(void);
-void tegra_idle_lp2_last(void);
 extern void (*tegra_tear_down_cpu)(void);
 
 #ifdef CONFIG_PM_SLEEP
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index d219872b7546..0d9956e9a8ea 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -124,7 +124,6 @@ void tegra30_hotplug_shutdown(void);
 #endif
 
 void tegra20_tear_down_cpu(void);
-int tegra30_sleep_cpu_secondary_finish(unsigned long);
 void tegra30_tear_down_cpu(void);
 
 #endif
diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
index b8aef62cc3f5..cf0f2cb5e109 100644
--- a/include/linux/clk/tegra.h
+++ b/include/linux/clk/tegra.h
@@ -108,6 +108,19 @@ static inline void tegra_cpu_clock_resume(void)
 
 	tegra_cpu_car_ops->resume();
 }
+#else
+static inline bool tegra_cpu_rail_off_ready(void)
+{
+	return false;
+}
+
+static inline void tegra_cpu_clock_suspend(void)
+{
+}
+
+static inline void tegra_cpu_clock_resume(void)
+{
+}
 #endif
 
 extern void tegra210_xusb_pll_hw_control_enable(void);
diff --git a/include/soc/tegra/pm.h b/include/soc/tegra/pm.h
index 951fcd738d55..fa18c2df5028 100644
--- a/include/soc/tegra/pm.h
+++ b/include/soc/tegra/pm.h
@@ -20,6 +20,12 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
 
 /* low-level resume entry point */
 void tegra_resume(void);
+
+int tegra30_sleep_cpu_secondary_finish(unsigned long arg);
+void tegra_clear_cpu_in_lp2(void);
+void tegra_set_cpu_in_lp2(void);
+int tegra_idle_lp2_last(void);
+void tegra_cpu_die(unsigned int cpu);
 #else
 static inline enum tegra_suspend_mode
 tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
@@ -30,6 +36,28 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
 static inline void tegra_resume(void)
 {
 }
+
+static inline int tegra30_sleep_cpu_secondary_finish(unsigned long arg)
+{
+	return -1;
+}
+
+static inline void tegra_clear_cpu_in_lp2(void)
+{
+}
+
+static inline void tegra_set_cpu_in_lp2(void)
+{
+}
+
+static inline int tegra_idle_lp2_last(void)
+{
+	return -1;
+}
+
+static inline void tegra_cpu_die(unsigned int cpu)
+{
+}
 #endif /* CONFIG_PM_SLEEP */
 
 #endif /* __SOC_TEGRA_PM_H__ */
-- 
2.22.0

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 2/6] ARM: tegra: Expose functions required for cpuidle driver
@ 2019-07-11  3:13   ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

The upcoming unified CPUIDLE driver will be added to the drivers/cpuidle/
directory and it will require all these Tegra PM-core functions.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/Makefile  |  2 +-
 arch/arm/mach-tegra/platsmp.c |  2 --
 arch/arm/mach-tegra/pm.c      | 16 +++++++---------
 arch/arm/mach-tegra/pm.h      |  3 ---
 arch/arm/mach-tegra/sleep.h   |  1 -
 include/linux/clk/tegra.h     | 13 +++++++++++++
 include/soc/tegra/pm.h        | 28 ++++++++++++++++++++++++++++
 7 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 5d93a0b36866..27bd5d9865e3 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pm-tegra20.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= pm-tegra30.o
 obj-$(CONFIG_SMP)			+= platsmp.o
-obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
+obj-y					+= hotplug.o
 
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= sleep-tegra30.o
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= pm-tegra30.o
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index e6911a14c096..c8a63719a143 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -183,8 +183,6 @@ const struct smp_operations tegra_smp_ops __initconst = {
 	.smp_prepare_cpus	= tegra_smp_prepare_cpus,
 	.smp_secondary_init	= tegra_secondary_init,
 	.smp_boot_secondary	= tegra_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
 	.cpu_kill		= tegra_cpu_kill,
 	.cpu_die		= tegra_cpu_die,
-#endif
 };
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 6aaacb5757e1..f9c9bce9e15d 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void)
 	spin_unlock(&tegra_lp2_lock);
 }
 
-bool tegra_set_cpu_in_lp2(void)
+void tegra_set_cpu_in_lp2(void)
 {
 	int phy_cpu_id = cpu_logical_map(smp_processor_id());
-	bool last_cpu = false;
-	cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
 	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
 
 	spin_lock(&tegra_lp2_lock);
@@ -135,11 +133,7 @@ bool tegra_set_cpu_in_lp2(void)
 	BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
 	*cpu_in_lp2 |= BIT(phy_cpu_id);
 
-	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
-		last_cpu = true;
-
 	spin_unlock(&tegra_lp2_lock);
-	return last_cpu;
 }
 
 static int tegra_sleep_cpu(unsigned long v2p)
@@ -195,14 +189,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
 	tegra_pmc_enter_suspend_mode(mode);
 }
 
-void tegra_idle_lp2_last(void)
+int tegra_idle_lp2_last(void)
 {
+	int err;
+
 	tegra_pm_set(TEGRA_SUSPEND_LP2);
 
 	cpu_cluster_pm_enter();
 	suspend_cpu_complex();
 
-	cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
+	err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
 
 	/*
 	 * Resume L2 cache if it wasn't re-enabled early during resume,
@@ -214,6 +210,8 @@ void tegra_idle_lp2_last(void)
 
 	restore_cpu_complex();
 	cpu_cluster_pm_exit();
+
+	return err;
 }
 
 enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
index 1e51a9b636eb..81525f5f4a44 100644
--- a/arch/arm/mach-tegra/pm.h
+++ b/arch/arm/mach-tegra/pm.h
@@ -23,9 +23,6 @@ void tegra20_sleep_core_init(void);
 void tegra30_lp1_iram_hook(void);
 void tegra30_sleep_core_init(void);
 
-void tegra_clear_cpu_in_lp2(void);
-bool tegra_set_cpu_in_lp2(void);
-void tegra_idle_lp2_last(void);
 extern void (*tegra_tear_down_cpu)(void);
 
 #ifdef CONFIG_PM_SLEEP
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index d219872b7546..0d9956e9a8ea 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -124,7 +124,6 @@ void tegra30_hotplug_shutdown(void);
 #endif
 
 void tegra20_tear_down_cpu(void);
-int tegra30_sleep_cpu_secondary_finish(unsigned long);
 void tegra30_tear_down_cpu(void);
 
 #endif
diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
index b8aef62cc3f5..cf0f2cb5e109 100644
--- a/include/linux/clk/tegra.h
+++ b/include/linux/clk/tegra.h
@@ -108,6 +108,19 @@ static inline void tegra_cpu_clock_resume(void)
 
 	tegra_cpu_car_ops->resume();
 }
+#else
+static inline bool tegra_cpu_rail_off_ready(void)
+{
+	return false;
+}
+
+static inline void tegra_cpu_clock_suspend(void)
+{
+}
+
+static inline void tegra_cpu_clock_resume(void)
+{
+}
 #endif
 
 extern void tegra210_xusb_pll_hw_control_enable(void);
diff --git a/include/soc/tegra/pm.h b/include/soc/tegra/pm.h
index 951fcd738d55..fa18c2df5028 100644
--- a/include/soc/tegra/pm.h
+++ b/include/soc/tegra/pm.h
@@ -20,6 +20,12 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
 
 /* low-level resume entry point */
 void tegra_resume(void);
+
+int tegra30_sleep_cpu_secondary_finish(unsigned long arg);
+void tegra_clear_cpu_in_lp2(void);
+void tegra_set_cpu_in_lp2(void);
+int tegra_idle_lp2_last(void);
+void tegra_cpu_die(unsigned int cpu);
 #else
 static inline enum tegra_suspend_mode
 tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
@@ -30,6 +36,28 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
 static inline void tegra_resume(void)
 {
 }
+
+static inline int tegra30_sleep_cpu_secondary_finish(unsigned long arg)
+{
+	return -1;
+}
+
+static inline void tegra_clear_cpu_in_lp2(void)
+{
+}
+
+static inline void tegra_set_cpu_in_lp2(void)
+{
+}
+
+static inline int tegra_idle_lp2_last(void)
+{
+	return -1;
+}
+
+static inline void tegra_cpu_die(unsigned int cpu)
+{
+}
 #endif /* CONFIG_PM_SLEEP */
 
 #endif /* __SOC_TEGRA_PM_H__ */
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 3/6] cpuidle: Add unified driver for NVIDIA Tegra SoCs
  2019-07-11  3:13 ` Dmitry Osipenko
@ 2019-07-11  3:13   ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

The new driver is based on the old CPU Idle drivers that are removed now
from arm/arch/mach-tegra/ directory. Those removed drivers were reworked
and squashed into a single unified driver that covers multiple hardware
generations, starting from Tegra20 and ending with Tegra124.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/tegra.c     |   4 +
 drivers/cpuidle/Kconfig.arm     |   8 +
 drivers/cpuidle/Makefile        |   1 +
 drivers/cpuidle/cpuidle-tegra.c | 304 ++++++++++++++++++++++++++++++++
 include/soc/tegra/cpuidle.h     |   4 +
 5 files changed, 321 insertions(+)
 create mode 100644 drivers/cpuidle/cpuidle-tegra.c

diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index d9237769a37c..f1ce2857a251 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -36,6 +36,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach-types.h>
+#include <asm/psci.h>
 #include <asm/setup.h>
 
 #include "board.h"
@@ -92,6 +93,9 @@ static void __init tegra_dt_init_late(void)
 	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
 	    of_machine_is_compatible("nvidia,tegra20"))
 		platform_device_register_simple("tegra20-cpufreq", -1, NULL, 0);
+
+	if (IS_ENABLED(CONFIG_ARM_TEGRA_CPUIDLE) && !psci_smp_available())
+		platform_device_register_simple("tegra-cpuidle", -1, NULL, 0);
 }
 
 static const char * const tegra_dt_board_compat[] = {
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 48cb3d4bb7d1..d90861361f1d 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -76,3 +76,11 @@ config ARM_MVEBU_V7_CPUIDLE
 	depends on ARCH_MVEBU && !ARM64
 	help
 	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
+
+config ARM_TEGRA_CPUIDLE
+	bool "CPU Idle Driver for NVIDIA Tegra SoCs"
+	depends on ARCH_TEGRA && !ARM64
+	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
+	select ARM_CPU_SUSPEND
+	help
+	  Select this to enable cpuidle for NVIDIA Tegra20/30/114/124 SoCs.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 9d7176cee3d3..470d17fa8746 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
 obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
 obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
 obj-$(CONFIG_ARM_CPUIDLE)		+= cpuidle-arm.o
+obj-$(CONFIG_ARM_TEGRA_CPUIDLE)		+= cpuidle-tegra.o
 
 ###############################################################################
 # MIPS drivers
diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c
new file mode 100644
index 000000000000..54974cd2255f
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-tegra.c
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * CPU idle driver for Tegra CPUs
+ *
+ * Copyright (c) 2010-2013, 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>
+ *
+ * Tegra20/124 driver unification by Dmitry Osipenko <digetx@gmail.com>
+ */
+
+#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/cpu_pm.h>
+#include <linux/errno.h>
+#include <linux/ktime.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include <linux/clk/tegra.h>
+#include <linux/firmware/trusted_foundations.h>
+
+#include <soc/tegra/cpuidle.h>
+#include <soc/tegra/flowctrl.h>
+#include <soc/tegra/fuse.h>
+#include <soc/tegra/pm.h>
+
+#include <asm/cpuidle.h>
+#include <asm/firmware.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+
+#define TEGRA_C1		0
+#define TEGRA_C7		1
+#define TEGRA_CC6		2
+
+static atomic_t tegra_idle_barrier;
+
+static inline bool tegra_cpuidle_using_firmware(void)
+{
+	return firmware_ops->prepare_idle && firmware_ops->do_idle;
+}
+
+static int tegra_shutdown_secondary_cpu(unsigned long cpu)
+{
+	tegra_cpu_die(cpu);
+
+	return -EINVAL;
+}
+
+static int tegra_await_secondary_cpus_shutdown(void)
+{
+	ktime_t timeout = ktime_add_ms(ktime_get(), 1);
+
+	/*
+	 * The boot CPU shall await for the secondaries shutdown in order
+	 * to power-off CPU's cluster safely.
+	 */
+	do {
+		if (tegra_cpu_rail_off_ready())
+			return 0;
+
+	} while (ktime_compare(ktime_get(), timeout) < 0);
+
+	return -ETIMEDOUT;
+}
+
+static void tegra_wake_up_secondary_cpus(void)
+{
+	unsigned int cpu, lcpu;
+
+	for_each_cpu(lcpu, cpu_online_mask) {
+		cpu = cpu_logical_map(lcpu);
+
+		if (cpu > 0) {
+			tegra_enable_cpu_clock(cpu);
+			tegra_cpu_out_of_reset(cpu);
+			flowctrl_write_cpu_halt(cpu, 0);
+		}
+	}
+}
+
+static int tegra_cpuidle_cc6_enter(void)
+{
+	int err;
+
+	err = tegra_await_secondary_cpus_shutdown();
+	if (err)
+		return err;
+
+	err = tegra_idle_lp2_last();
+
+	tegra_wake_up_secondary_cpus();
+
+	return err;
+}
+
+static int tegra_cpuidle_c7_enter(void)
+{
+	int err;
+
+	if (tegra_cpuidle_using_firmware()) {
+		err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
+		if (err)
+			return err;
+
+		return call_firmware_op(do_idle, 0);
+	}
+
+	return cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
+}
+
+static int tegra_cpuidle_enter(struct cpuidle_device *dev,
+			       int index, unsigned int cpu)
+{
+	int err;
+
+	local_fiq_disable();
+	tegra_set_cpu_in_lp2();
+	cpu_pm_enter();
+
+	switch (index) {
+	case TEGRA_C7:
+		err = tegra_cpuidle_c7_enter();
+		break;
+	case TEGRA_CC6:
+		cpuidle_coupled_parallel_barrier(dev, &tegra_idle_barrier);
+
+		if (cpu > 0)
+			err = cpu_suspend(cpu, tegra_shutdown_secondary_cpu);
+		else
+			err = tegra_cpuidle_cc6_enter();
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+
+	cpu_pm_exit();
+	tegra_clear_cpu_in_lp2();
+	local_fiq_enable();
+
+	smp_rmb();
+
+	return err;
+}
+
+static int tegra_adjust_state_index(struct cpuidle_device *dev,
+				    struct cpuidle_driver *drv,
+				    int index, unsigned int cpu)
+{
+	/*
+	 * On Tegra30 CPU0 can't be power-gated while secondary CPUs
+	 * are active because it gates the whole CPU cluster.
+	 */
+	if (cpu != 0 || index != TEGRA_C7 || tegra_get_chip_id() != TEGRA30)
+		return index;
+
+	if (!IS_ENABLED(CONFIG_PM_SLEEP) || num_online_cpus() > 1)
+		index = TEGRA_C1;
+	else
+		index = TEGRA_CC6;
+
+	if (drv->states[index].disabled || dev->states_usage[index].disable)
+		index = -1;
+
+	return index;
+}
+
+static int tegra_cpu_idle(struct cpuidle_device *dev,
+			  struct cpuidle_driver *drv,
+			  int index)
+{
+	unsigned int cpu = cpu_logical_map(dev->cpu);
+	int err;
+
+	index = tegra_adjust_state_index(dev, drv, index, cpu);
+	if (index < 0)
+		return index;
+
+	if (index == TEGRA_C1)
+		err = arm_cpuidle_simple_enter(dev, drv, index);
+	else
+		err = tegra_cpuidle_enter(dev, index, cpu);
+
+	return WARN_ON_ONCE(err) ? -1 : index;
+}
+
+static void tegra114_enter_s2idle(struct cpuidle_device *dev,
+				  struct cpuidle_driver *drv,
+				  int index)
+{
+	tegra_cpu_idle(dev, drv, index);
+}
+
+static struct cpuidle_driver tegra_idle_driver = {
+	.name = "tegra_idle",
+	.states = {
+		[TEGRA_C1] = ARM_CPUIDLE_WFI_STATE_PWR(600),
+		[TEGRA_C7] = {
+			.enter			= tegra_cpu_idle,
+			.exit_latency		= 2000,
+			.target_residency	= 2200,
+			.power_usage		= 100,
+			.flags			= CPUIDLE_FLAG_TIMER_STOP,
+			.name			= "C7",
+			.desc			= "CPU core powered off",
+		},
+		[TEGRA_CC6] = {
+			.enter			= tegra_cpu_idle,
+			.exit_latency		= 5000,
+			.target_residency	= 10000,
+			.power_usage		= 0,
+			.flags			= CPUIDLE_FLAG_TIMER_STOP |
+						  CPUIDLE_FLAG_COUPLED,
+			.name			= "CC6",
+			.desc			= "CPU cluster powered off",
+		},
+	},
+	.state_count = 3,
+	.safe_state_index = TEGRA_C1,
+};
+
+/*
+ * 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 tegra_cpuidle_pcie_irqs_in_use(void)
+{
+	if (tegra_get_chip_id() != TEGRA20 ||
+	    tegra_idle_driver.states[TEGRA_CC6].disabled)
+		return;
+
+	pr_info("Disabling cpuidle LP2 state, since PCIe IRQs are in use\n");
+	tegra_idle_driver.states[TEGRA_CC6].disabled = true;
+}
+
+static void tegra_cpuidle_adjust_tegra114_c7_state(void)
+{
+	struct cpuidle_state *s = &tegra_idle_driver.states[TEGRA_C7];
+
+	s->enter_s2idle = tegra114_enter_s2idle;
+	s->target_residency = 1000;
+	s->exit_latency = 500;
+}
+
+static int tegra_cpuidle_probe(struct platform_device *pdev)
+{
+	/*
+	 * Tegra30+ SoCs are big.LITTLE architectures, but the Little
+	 * core is not supported at the moment.
+	 */
+	const struct cpumask *coupled_cpus = cpu_possible_mask;
+
+	/*
+	 * Required suspend-resume functionality, which is provided by the
+	 * Tegra-arch core and PMC driver, is unavailable if PM-sleep option
+	 * is disabled.
+	 */
+	if (!IS_ENABLED(CONFIG_PM_SLEEP)) {
+		if (!tegra_cpuidle_using_firmware())
+			tegra_idle_driver.states[TEGRA_C7].disabled = true;
+
+		tegra_idle_driver.states[TEGRA_CC6].disabled = true;
+	}
+
+	/*
+	 * Generic WFI state (also known as C1 or LP3) is common for all
+	 * NVIDIA Tegra SoCs.
+	 */
+	switch (tegra_get_chip_id()) {
+	case TEGRA20:
+		/* CPU cores can't be power-gated separately at all */
+		tegra_idle_driver.states[TEGRA_C7].disabled = true;
+		break;
+	case TEGRA30:
+		tegra_idle_driver.states[TEGRA_CC6].disabled = true;
+		break;
+	case TEGRA114:
+	case TEGRA124:
+		tegra_cpuidle_adjust_tegra114_c7_state();
+
+		/* coupled CC6 (LP2) state isn't implemented yet */
+		tegra_idle_driver.states[TEGRA_CC6].disabled = true;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return cpuidle_register(&tegra_idle_driver, coupled_cpus);
+}
+
+static struct platform_driver tegra_cpuidle_driver = {
+	.probe = tegra_cpuidle_probe,
+	.driver = {
+		.name = "tegra-cpuidle",
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver(tegra_cpuidle_driver);
diff --git a/include/soc/tegra/cpuidle.h b/include/soc/tegra/cpuidle.h
index f758808342b6..5665975015d8 100644
--- a/include/soc/tegra/cpuidle.h
+++ b/include/soc/tegra/cpuidle.h
@@ -6,8 +6,12 @@
 #ifndef __SOC_TEGRA_CPUIDLE_H__
 #define __SOC_TEGRA_CPUIDLE_H__
 
+#ifdef CONFIG_ARM_TEGRA_CPUIDLE
+void tegra_cpuidle_pcie_irqs_in_use(void);
+#else
 static inline void tegra_cpuidle_pcie_irqs_in_use(void)
 {
 }
+#endif
 
 #endif /* __SOC_TEGRA_CPUIDLE_H__ */
-- 
2.22.0

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 3/6] cpuidle: Add unified driver for NVIDIA Tegra SoCs
@ 2019-07-11  3:13   ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

The new driver is based on the old CPU Idle drivers that are removed now
from arm/arch/mach-tegra/ directory. Those removed drivers were reworked
and squashed into a single unified driver that covers multiple hardware
generations, starting from Tegra20 and ending with Tegra124.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/tegra.c     |   4 +
 drivers/cpuidle/Kconfig.arm     |   8 +
 drivers/cpuidle/Makefile        |   1 +
 drivers/cpuidle/cpuidle-tegra.c | 304 ++++++++++++++++++++++++++++++++
 include/soc/tegra/cpuidle.h     |   4 +
 5 files changed, 321 insertions(+)
 create mode 100644 drivers/cpuidle/cpuidle-tegra.c

diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index d9237769a37c..f1ce2857a251 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -36,6 +36,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach-types.h>
+#include <asm/psci.h>
 #include <asm/setup.h>
 
 #include "board.h"
@@ -92,6 +93,9 @@ static void __init tegra_dt_init_late(void)
 	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
 	    of_machine_is_compatible("nvidia,tegra20"))
 		platform_device_register_simple("tegra20-cpufreq", -1, NULL, 0);
+
+	if (IS_ENABLED(CONFIG_ARM_TEGRA_CPUIDLE) && !psci_smp_available())
+		platform_device_register_simple("tegra-cpuidle", -1, NULL, 0);
 }
 
 static const char * const tegra_dt_board_compat[] = {
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 48cb3d4bb7d1..d90861361f1d 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -76,3 +76,11 @@ config ARM_MVEBU_V7_CPUIDLE
 	depends on ARCH_MVEBU && !ARM64
 	help
 	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
+
+config ARM_TEGRA_CPUIDLE
+	bool "CPU Idle Driver for NVIDIA Tegra SoCs"
+	depends on ARCH_TEGRA && !ARM64
+	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
+	select ARM_CPU_SUSPEND
+	help
+	  Select this to enable cpuidle for NVIDIA Tegra20/30/114/124 SoCs.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 9d7176cee3d3..470d17fa8746 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
 obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
 obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
 obj-$(CONFIG_ARM_CPUIDLE)		+= cpuidle-arm.o
+obj-$(CONFIG_ARM_TEGRA_CPUIDLE)		+= cpuidle-tegra.o
 
 ###############################################################################
 # MIPS drivers
diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c
new file mode 100644
index 000000000000..54974cd2255f
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-tegra.c
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * CPU idle driver for Tegra CPUs
+ *
+ * Copyright (c) 2010-2013, 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>
+ *
+ * Tegra20/124 driver unification by Dmitry Osipenko <digetx@gmail.com>
+ */
+
+#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/cpu_pm.h>
+#include <linux/errno.h>
+#include <linux/ktime.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include <linux/clk/tegra.h>
+#include <linux/firmware/trusted_foundations.h>
+
+#include <soc/tegra/cpuidle.h>
+#include <soc/tegra/flowctrl.h>
+#include <soc/tegra/fuse.h>
+#include <soc/tegra/pm.h>
+
+#include <asm/cpuidle.h>
+#include <asm/firmware.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+
+#define TEGRA_C1		0
+#define TEGRA_C7		1
+#define TEGRA_CC6		2
+
+static atomic_t tegra_idle_barrier;
+
+static inline bool tegra_cpuidle_using_firmware(void)
+{
+	return firmware_ops->prepare_idle && firmware_ops->do_idle;
+}
+
+static int tegra_shutdown_secondary_cpu(unsigned long cpu)
+{
+	tegra_cpu_die(cpu);
+
+	return -EINVAL;
+}
+
+static int tegra_await_secondary_cpus_shutdown(void)
+{
+	ktime_t timeout = ktime_add_ms(ktime_get(), 1);
+
+	/*
+	 * The boot CPU shall await for the secondaries shutdown in order
+	 * to power-off CPU's cluster safely.
+	 */
+	do {
+		if (tegra_cpu_rail_off_ready())
+			return 0;
+
+	} while (ktime_compare(ktime_get(), timeout) < 0);
+
+	return -ETIMEDOUT;
+}
+
+static void tegra_wake_up_secondary_cpus(void)
+{
+	unsigned int cpu, lcpu;
+
+	for_each_cpu(lcpu, cpu_online_mask) {
+		cpu = cpu_logical_map(lcpu);
+
+		if (cpu > 0) {
+			tegra_enable_cpu_clock(cpu);
+			tegra_cpu_out_of_reset(cpu);
+			flowctrl_write_cpu_halt(cpu, 0);
+		}
+	}
+}
+
+static int tegra_cpuidle_cc6_enter(void)
+{
+	int err;
+
+	err = tegra_await_secondary_cpus_shutdown();
+	if (err)
+		return err;
+
+	err = tegra_idle_lp2_last();
+
+	tegra_wake_up_secondary_cpus();
+
+	return err;
+}
+
+static int tegra_cpuidle_c7_enter(void)
+{
+	int err;
+
+	if (tegra_cpuidle_using_firmware()) {
+		err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
+		if (err)
+			return err;
+
+		return call_firmware_op(do_idle, 0);
+	}
+
+	return cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
+}
+
+static int tegra_cpuidle_enter(struct cpuidle_device *dev,
+			       int index, unsigned int cpu)
+{
+	int err;
+
+	local_fiq_disable();
+	tegra_set_cpu_in_lp2();
+	cpu_pm_enter();
+
+	switch (index) {
+	case TEGRA_C7:
+		err = tegra_cpuidle_c7_enter();
+		break;
+	case TEGRA_CC6:
+		cpuidle_coupled_parallel_barrier(dev, &tegra_idle_barrier);
+
+		if (cpu > 0)
+			err = cpu_suspend(cpu, tegra_shutdown_secondary_cpu);
+		else
+			err = tegra_cpuidle_cc6_enter();
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+
+	cpu_pm_exit();
+	tegra_clear_cpu_in_lp2();
+	local_fiq_enable();
+
+	smp_rmb();
+
+	return err;
+}
+
+static int tegra_adjust_state_index(struct cpuidle_device *dev,
+				    struct cpuidle_driver *drv,
+				    int index, unsigned int cpu)
+{
+	/*
+	 * On Tegra30 CPU0 can't be power-gated while secondary CPUs
+	 * are active because it gates the whole CPU cluster.
+	 */
+	if (cpu != 0 || index != TEGRA_C7 || tegra_get_chip_id() != TEGRA30)
+		return index;
+
+	if (!IS_ENABLED(CONFIG_PM_SLEEP) || num_online_cpus() > 1)
+		index = TEGRA_C1;
+	else
+		index = TEGRA_CC6;
+
+	if (drv->states[index].disabled || dev->states_usage[index].disable)
+		index = -1;
+
+	return index;
+}
+
+static int tegra_cpu_idle(struct cpuidle_device *dev,
+			  struct cpuidle_driver *drv,
+			  int index)
+{
+	unsigned int cpu = cpu_logical_map(dev->cpu);
+	int err;
+
+	index = tegra_adjust_state_index(dev, drv, index, cpu);
+	if (index < 0)
+		return index;
+
+	if (index == TEGRA_C1)
+		err = arm_cpuidle_simple_enter(dev, drv, index);
+	else
+		err = tegra_cpuidle_enter(dev, index, cpu);
+
+	return WARN_ON_ONCE(err) ? -1 : index;
+}
+
+static void tegra114_enter_s2idle(struct cpuidle_device *dev,
+				  struct cpuidle_driver *drv,
+				  int index)
+{
+	tegra_cpu_idle(dev, drv, index);
+}
+
+static struct cpuidle_driver tegra_idle_driver = {
+	.name = "tegra_idle",
+	.states = {
+		[TEGRA_C1] = ARM_CPUIDLE_WFI_STATE_PWR(600),
+		[TEGRA_C7] = {
+			.enter			= tegra_cpu_idle,
+			.exit_latency		= 2000,
+			.target_residency	= 2200,
+			.power_usage		= 100,
+			.flags			= CPUIDLE_FLAG_TIMER_STOP,
+			.name			= "C7",
+			.desc			= "CPU core powered off",
+		},
+		[TEGRA_CC6] = {
+			.enter			= tegra_cpu_idle,
+			.exit_latency		= 5000,
+			.target_residency	= 10000,
+			.power_usage		= 0,
+			.flags			= CPUIDLE_FLAG_TIMER_STOP |
+						  CPUIDLE_FLAG_COUPLED,
+			.name			= "CC6",
+			.desc			= "CPU cluster powered off",
+		},
+	},
+	.state_count = 3,
+	.safe_state_index = TEGRA_C1,
+};
+
+/*
+ * 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 tegra_cpuidle_pcie_irqs_in_use(void)
+{
+	if (tegra_get_chip_id() != TEGRA20 ||
+	    tegra_idle_driver.states[TEGRA_CC6].disabled)
+		return;
+
+	pr_info("Disabling cpuidle LP2 state, since PCIe IRQs are in use\n");
+	tegra_idle_driver.states[TEGRA_CC6].disabled = true;
+}
+
+static void tegra_cpuidle_adjust_tegra114_c7_state(void)
+{
+	struct cpuidle_state *s = &tegra_idle_driver.states[TEGRA_C7];
+
+	s->enter_s2idle = tegra114_enter_s2idle;
+	s->target_residency = 1000;
+	s->exit_latency = 500;
+}
+
+static int tegra_cpuidle_probe(struct platform_device *pdev)
+{
+	/*
+	 * Tegra30+ SoCs are big.LITTLE architectures, but the Little
+	 * core is not supported at the moment.
+	 */
+	const struct cpumask *coupled_cpus = cpu_possible_mask;
+
+	/*
+	 * Required suspend-resume functionality, which is provided by the
+	 * Tegra-arch core and PMC driver, is unavailable if PM-sleep option
+	 * is disabled.
+	 */
+	if (!IS_ENABLED(CONFIG_PM_SLEEP)) {
+		if (!tegra_cpuidle_using_firmware())
+			tegra_idle_driver.states[TEGRA_C7].disabled = true;
+
+		tegra_idle_driver.states[TEGRA_CC6].disabled = true;
+	}
+
+	/*
+	 * Generic WFI state (also known as C1 or LP3) is common for all
+	 * NVIDIA Tegra SoCs.
+	 */
+	switch (tegra_get_chip_id()) {
+	case TEGRA20:
+		/* CPU cores can't be power-gated separately at all */
+		tegra_idle_driver.states[TEGRA_C7].disabled = true;
+		break;
+	case TEGRA30:
+		tegra_idle_driver.states[TEGRA_CC6].disabled = true;
+		break;
+	case TEGRA114:
+	case TEGRA124:
+		tegra_cpuidle_adjust_tegra114_c7_state();
+
+		/* coupled CC6 (LP2) state isn't implemented yet */
+		tegra_idle_driver.states[TEGRA_CC6].disabled = true;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return cpuidle_register(&tegra_idle_driver, coupled_cpus);
+}
+
+static struct platform_driver tegra_cpuidle_driver = {
+	.probe = tegra_cpuidle_probe,
+	.driver = {
+		.name = "tegra-cpuidle",
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver(tegra_cpuidle_driver);
diff --git a/include/soc/tegra/cpuidle.h b/include/soc/tegra/cpuidle.h
index f758808342b6..5665975015d8 100644
--- a/include/soc/tegra/cpuidle.h
+++ b/include/soc/tegra/cpuidle.h
@@ -6,8 +6,12 @@
 #ifndef __SOC_TEGRA_CPUIDLE_H__
 #define __SOC_TEGRA_CPUIDLE_H__
 
+#ifdef CONFIG_ARM_TEGRA_CPUIDLE
+void tegra_cpuidle_pcie_irqs_in_use(void);
+#else
 static inline void tegra_cpuidle_pcie_irqs_in_use(void)
 {
 }
+#endif
 
 #endif /* __SOC_TEGRA_CPUIDLE_H__ */
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 4/6] cpuidle: tegra: Support CPU cluster power-down on Tegra30
  2019-07-11  3:13 ` Dmitry Osipenko
@ 2019-07-11  3:13   ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

The new CPU Idle driver has all necessary features in order to allow
the deepest idling state on Tegra30 SoC where the whole CPU cluster is
power-gated using the coupled idle state.

Note that outer_disable() now need to be invoked directly since it
produces erroneous warning message about secondary CPUs being online
because it doesn't know that secondaries are turned off at that point
by the cpuidle driver.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/pm.c        | 4 ++--
 drivers/cpuidle/cpuidle-tegra.c | 1 -
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index f9c9bce9e15d..cc941b0c97e8 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -146,8 +146,8 @@ static int tegra_sleep_cpu(unsigned long v2p)
 	 * if any of secondary CPU's is online and this is the LP2-idle
 	 * code-path only for Tegra20/30.
 	 */
-	if (trusted_foundations_registered())
-		outer_disable();
+	if (trusted_foundations_registered() && outer_cache.disable)
+		outer_cache.disable();
 
 	/*
 	 * Note that besides of setting up CPU reset vector this firmware
diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c
index 54974cd2255f..1412c4b0f6ee 100644
--- a/drivers/cpuidle/cpuidle-tegra.c
+++ b/drivers/cpuidle/cpuidle-tegra.c
@@ -278,7 +278,6 @@ static int tegra_cpuidle_probe(struct platform_device *pdev)
 		tegra_idle_driver.states[TEGRA_C7].disabled = true;
 		break;
 	case TEGRA30:
-		tegra_idle_driver.states[TEGRA_CC6].disabled = true;
 		break;
 	case TEGRA114:
 	case TEGRA124:
-- 
2.22.0

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 4/6] cpuidle: tegra: Support CPU cluster power-down on Tegra30
@ 2019-07-11  3:13   ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

The new CPU Idle driver has all necessary features in order to allow
the deepest idling state on Tegra30 SoC where the whole CPU cluster is
power-gated using the coupled idle state.

Note that outer_disable() now need to be invoked directly since it
produces erroneous warning message about secondary CPUs being online
because it doesn't know that secondaries are turned off at that point
by the cpuidle driver.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/mach-tegra/pm.c        | 4 ++--
 drivers/cpuidle/cpuidle-tegra.c | 1 -
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index f9c9bce9e15d..cc941b0c97e8 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -146,8 +146,8 @@ static int tegra_sleep_cpu(unsigned long v2p)
 	 * if any of secondary CPU's is online and this is the LP2-idle
 	 * code-path only for Tegra20/30.
 	 */
-	if (trusted_foundations_registered())
-		outer_disable();
+	if (trusted_foundations_registered() && outer_cache.disable)
+		outer_cache.disable();
 
 	/*
 	 * Note that besides of setting up CPU reset vector this firmware
diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c
index 54974cd2255f..1412c4b0f6ee 100644
--- a/drivers/cpuidle/cpuidle-tegra.c
+++ b/drivers/cpuidle/cpuidle-tegra.c
@@ -278,7 +278,6 @@ static int tegra_cpuidle_probe(struct platform_device *pdev)
 		tegra_idle_driver.states[TEGRA_C7].disabled = true;
 		break;
 	case TEGRA30:
-		tegra_idle_driver.states[TEGRA_CC6].disabled = true;
 		break;
 	case TEGRA114:
 	case TEGRA124:
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 5/6] ARM: multi_v7_defconfig: Enable Tegra cpuidle driver
  2019-07-11  3:13 ` Dmitry Osipenko
@ 2019-07-11  3:13   ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

The Tegra CPU Idle driver was moved out into driver/cpuidle/ directory and
it is now a proper platform driver.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 6a40bc2ef271..2c0fc7968c42 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -107,6 +107,7 @@ CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_ARM_ZYNQ_CPUIDLE=y
 CONFIG_ARM_EXYNOS_CPUIDLE=y
+CONFIG_ARM_TEGRA_CPUIDLE=y
 CONFIG_KERNEL_MODE_NEON=y
 CONFIG_RASPBERRYPI_FIRMWARE=y
 CONFIG_TRUSTED_FOUNDATIONS=y
-- 
2.22.0

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 5/6] ARM: multi_v7_defconfig: Enable Tegra cpuidle driver
@ 2019-07-11  3:13   ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

The Tegra CPU Idle driver was moved out into driver/cpuidle/ directory and
it is now a proper platform driver.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 6a40bc2ef271..2c0fc7968c42 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -107,6 +107,7 @@ CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_ARM_ZYNQ_CPUIDLE=y
 CONFIG_ARM_EXYNOS_CPUIDLE=y
+CONFIG_ARM_TEGRA_CPUIDLE=y
 CONFIG_KERNEL_MODE_NEON=y
 CONFIG_RASPBERRYPI_FIRMWARE=y
 CONFIG_TRUSTED_FOUNDATIONS=y
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 6/6] ARM: tegra: Enable Tegra cpuidle driver in tegra_defconfig
  2019-07-11  3:13 ` Dmitry Osipenko
@ 2019-07-11  3:13   ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

The Tegra CPU Idle driver was moved out into driver/cpuidle/ directory and
it is now a proper platform driver.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/configs/tegra_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 8f5c6a5b444c..9a2f11a780a8 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -25,6 +25,7 @@ CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_CPU_IDLE=y
+CONFIG_ARM_TEGRA_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_TRUSTED_FOUNDATIONS=y
-- 
2.22.0

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v2 6/6] ARM: tegra: Enable Tegra cpuidle driver in tegra_defconfig
@ 2019-07-11  3:13   ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11  3:13 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

The Tegra CPU Idle driver was moved out into driver/cpuidle/ directory and
it is now a proper platform driver.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/configs/tegra_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 8f5c6a5b444c..9a2f11a780a8 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -25,6 +25,7 @@ CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_CPU_IDLE=y
+CONFIG_ARM_TEGRA_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_TRUSTED_FOUNDATIONS=y
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
  2019-07-11  3:13   ` Dmitry Osipenko
  (?)
@ 2019-07-11  9:26     ` Jon Hunter
  -1 siblings, 0 replies; 35+ messages in thread
From: Jon Hunter @ 2019-07-11  9:26 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel


On 11/07/2019 04:13, Dmitry Osipenko wrote:
> Remove the old drivers to replace them cleanly with a new one later on.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/mach-tegra/Makefile           |  13 --
>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>  arch/arm/mach-tegra/irq.c              |  18 ---
>  arch/arm/mach-tegra/irq.h              |  11 --
>  arch/arm/mach-tegra/pm.c               |   7 -
>  arch/arm/mach-tegra/pm.h               |   1 -
>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>  arch/arm/mach-tegra/reset.h            |   9 +-
>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>  arch/arm/mach-tegra/sleep.h            |  12 --
>  arch/arm/mach-tegra/tegra.c            |   3 -
>  drivers/soc/tegra/Kconfig              |   1 -
>  include/soc/tegra/cpuidle.h            |   4 -
>  17 files changed, 5 insertions(+), 779 deletions(-)
>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>  delete mode 100644 arch/arm/mach-tegra/irq.h

By removing all the above, it is really hard to review the diff. Is
there any way you could first consolidate the cpuidle drivers into say
the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
drivers/cpuidle?

Jon

-- 
nvpublic

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
@ 2019-07-11  9:26     ` Jon Hunter
  0 siblings, 0 replies; 35+ messages in thread
From: Jon Hunter @ 2019-07-11  9:26 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel


On 11/07/2019 04:13, Dmitry Osipenko wrote:
> Remove the old drivers to replace them cleanly with a new one later on.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/mach-tegra/Makefile           |  13 --
>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>  arch/arm/mach-tegra/irq.c              |  18 ---
>  arch/arm/mach-tegra/irq.h              |  11 --
>  arch/arm/mach-tegra/pm.c               |   7 -
>  arch/arm/mach-tegra/pm.h               |   1 -
>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>  arch/arm/mach-tegra/reset.h            |   9 +-
>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>  arch/arm/mach-tegra/sleep.h            |  12 --
>  arch/arm/mach-tegra/tegra.c            |   3 -
>  drivers/soc/tegra/Kconfig              |   1 -
>  include/soc/tegra/cpuidle.h            |   4 -
>  17 files changed, 5 insertions(+), 779 deletions(-)
>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>  delete mode 100644 arch/arm/mach-tegra/irq.h

By removing all the above, it is really hard to review the diff. Is
there any way you could first consolidate the cpuidle drivers into say
the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
drivers/cpuidle?

Jon

-- 
nvpublic

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
@ 2019-07-11  9:26     ` Jon Hunter
  0 siblings, 0 replies; 35+ messages in thread
From: Jon Hunter @ 2019-07-11  9:26 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm


On 11/07/2019 04:13, Dmitry Osipenko wrote:
> Remove the old drivers to replace them cleanly with a new one later on.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/mach-tegra/Makefile           |  13 --
>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>  arch/arm/mach-tegra/irq.c              |  18 ---
>  arch/arm/mach-tegra/irq.h              |  11 --
>  arch/arm/mach-tegra/pm.c               |   7 -
>  arch/arm/mach-tegra/pm.h               |   1 -
>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>  arch/arm/mach-tegra/reset.h            |   9 +-
>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>  arch/arm/mach-tegra/sleep.h            |  12 --
>  arch/arm/mach-tegra/tegra.c            |   3 -
>  drivers/soc/tegra/Kconfig              |   1 -
>  include/soc/tegra/cpuidle.h            |   4 -
>  17 files changed, 5 insertions(+), 779 deletions(-)
>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>  delete mode 100644 arch/arm/mach-tegra/irq.h

By removing all the above, it is really hard to review the diff. Is
there any way you could first consolidate the cpuidle drivers into say
the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
drivers/cpuidle?

Jon

-- 
nvpublic

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 2/6] ARM: tegra: Expose functions required for cpuidle driver
  2019-07-11  3:13   ` Dmitry Osipenko
  (?)
@ 2019-07-11 12:42     ` Jon Hunter
  -1 siblings, 0 replies; 35+ messages in thread
From: Jon Hunter @ 2019-07-11 12:42 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel


On 11/07/2019 04:13, Dmitry Osipenko wrote:
> The upcoming unified CPUIDLE driver will be added to the drivers/cpuidle/
> directory and it will require all these Tegra PM-core functions.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/mach-tegra/Makefile  |  2 +-
>  arch/arm/mach-tegra/platsmp.c |  2 --
>  arch/arm/mach-tegra/pm.c      | 16 +++++++---------
>  arch/arm/mach-tegra/pm.h      |  3 ---
>  arch/arm/mach-tegra/sleep.h   |  1 -
>  include/linux/clk/tegra.h     | 13 +++++++++++++
>  include/soc/tegra/pm.h        | 28 ++++++++++++++++++++++++++++
>  7 files changed, 49 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
> index 5d93a0b36866..27bd5d9865e3 100644
> --- a/arch/arm/mach-tegra/Makefile
> +++ b/arch/arm/mach-tegra/Makefile
> @@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pm-tegra20.o
>  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-tegra30.o
>  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= pm-tegra30.o
>  obj-$(CONFIG_SMP)			+= platsmp.o
> -obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
> +obj-y					+= hotplug.o
>  
>  obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= sleep-tegra30.o
>  obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= pm-tegra30.o
> diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
> index e6911a14c096..c8a63719a143 100644
> --- a/arch/arm/mach-tegra/platsmp.c
> +++ b/arch/arm/mach-tegra/platsmp.c
> @@ -183,8 +183,6 @@ const struct smp_operations tegra_smp_ops __initconst = {
>  	.smp_prepare_cpus	= tegra_smp_prepare_cpus,
>  	.smp_secondary_init	= tegra_secondary_init,
>  	.smp_boot_secondary	= tegra_boot_secondary,
> -#ifdef CONFIG_HOTPLUG_CPU
>  	.cpu_kill		= tegra_cpu_kill,
>  	.cpu_die		= tegra_cpu_die,
> -#endif
>  };
> diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
> index 6aaacb5757e1..f9c9bce9e15d 100644
> --- a/arch/arm/mach-tegra/pm.c
> +++ b/arch/arm/mach-tegra/pm.c
> @@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void)
>  	spin_unlock(&tegra_lp2_lock);
>  }
>  
> -bool tegra_set_cpu_in_lp2(void)
> +void tegra_set_cpu_in_lp2(void)
>  {
>  	int phy_cpu_id = cpu_logical_map(smp_processor_id());
> -	bool last_cpu = false;
> -	cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
>  	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
>  
>  	spin_lock(&tegra_lp2_lock);
> @@ -135,11 +133,7 @@ bool tegra_set_cpu_in_lp2(void)
>  	BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
>  	*cpu_in_lp2 |= BIT(phy_cpu_id);
>  
> -	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
> -		last_cpu = true;
> -
>  	spin_unlock(&tegra_lp2_lock);
> -	return last_cpu;
>  }

I think that the commit message should describe what is going on here or
this should be a separate change.

>  
>  static int tegra_sleep_cpu(unsigned long v2p)
> @@ -195,14 +189,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
>  	tegra_pmc_enter_suspend_mode(mode);
>  }
>  
> -void tegra_idle_lp2_last(void)
> +int tegra_idle_lp2_last(void)
>  {
> +	int err;
> +
>  	tegra_pm_set(TEGRA_SUSPEND_LP2);
>  
>  	cpu_cluster_pm_enter();
>  	suspend_cpu_complex();
>  
> -	cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
> +	err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
>  
>  	/*
>  	 * Resume L2 cache if it wasn't re-enabled early during resume,
> @@ -214,6 +210,8 @@ void tegra_idle_lp2_last(void)
>  
>  	restore_cpu_complex();
>  	cpu_cluster_pm_exit();
> +
> +	return err;
>  }
>  
>  enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
> diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
> index 1e51a9b636eb..81525f5f4a44 100644
> --- a/arch/arm/mach-tegra/pm.h
> +++ b/arch/arm/mach-tegra/pm.h
> @@ -23,9 +23,6 @@ void tegra20_sleep_core_init(void);
>  void tegra30_lp1_iram_hook(void);
>  void tegra30_sleep_core_init(void);
>  
> -void tegra_clear_cpu_in_lp2(void);
> -bool tegra_set_cpu_in_lp2(void);
> -void tegra_idle_lp2_last(void);
>  extern void (*tegra_tear_down_cpu)(void);
>  
>  #ifdef CONFIG_PM_SLEEP
> diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
> index d219872b7546..0d9956e9a8ea 100644
> --- a/arch/arm/mach-tegra/sleep.h
> +++ b/arch/arm/mach-tegra/sleep.h
> @@ -124,7 +124,6 @@ void tegra30_hotplug_shutdown(void);
>  #endif
>  
>  void tegra20_tear_down_cpu(void);
> -int tegra30_sleep_cpu_secondary_finish(unsigned long);
>  void tegra30_tear_down_cpu(void);
>  
>  #endif
> diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
> index b8aef62cc3f5..cf0f2cb5e109 100644
> --- a/include/linux/clk/tegra.h
> +++ b/include/linux/clk/tegra.h
> @@ -108,6 +108,19 @@ static inline void tegra_cpu_clock_resume(void)
>  
>  	tegra_cpu_car_ops->resume();
>  }
> +#else
> +static inline bool tegra_cpu_rail_off_ready(void)
> +{
> +	return false;
> +}
> +
> +static inline void tegra_cpu_clock_suspend(void)
> +{
> +}
> +
> +static inline void tegra_cpu_clock_resume(void)
> +{
> +}
>  #endif
>  
>  extern void tegra210_xusb_pll_hw_control_enable(void);
> diff --git a/include/soc/tegra/pm.h b/include/soc/tegra/pm.h
> index 951fcd738d55..fa18c2df5028 100644
> --- a/include/soc/tegra/pm.h
> +++ b/include/soc/tegra/pm.h
> @@ -20,6 +20,12 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
>  
>  /* low-level resume entry point */
>  void tegra_resume(void);
> +
> +int tegra30_sleep_cpu_secondary_finish(unsigned long arg);
> +void tegra_clear_cpu_in_lp2(void);
> +void tegra_set_cpu_in_lp2(void);
> +int tegra_idle_lp2_last(void);
> +void tegra_cpu_die(unsigned int cpu);
>  #else
>  static inline enum tegra_suspend_mode
>  tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
> @@ -30,6 +36,28 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
>  static inline void tegra_resume(void)
>  {
>  }
> +
> +static inline int tegra30_sleep_cpu_secondary_finish(unsigned long arg)
> +{
> +	return -1;
> +}

-ENOTSUPP?

Jon

-- 
nvpublic

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 2/6] ARM: tegra: Expose functions required for cpuidle driver
@ 2019-07-11 12:42     ` Jon Hunter
  0 siblings, 0 replies; 35+ messages in thread
From: Jon Hunter @ 2019-07-11 12:42 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel


On 11/07/2019 04:13, Dmitry Osipenko wrote:
> The upcoming unified CPUIDLE driver will be added to the drivers/cpuidle/
> directory and it will require all these Tegra PM-core functions.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/mach-tegra/Makefile  |  2 +-
>  arch/arm/mach-tegra/platsmp.c |  2 --
>  arch/arm/mach-tegra/pm.c      | 16 +++++++---------
>  arch/arm/mach-tegra/pm.h      |  3 ---
>  arch/arm/mach-tegra/sleep.h   |  1 -
>  include/linux/clk/tegra.h     | 13 +++++++++++++
>  include/soc/tegra/pm.h        | 28 ++++++++++++++++++++++++++++
>  7 files changed, 49 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
> index 5d93a0b36866..27bd5d9865e3 100644
> --- a/arch/arm/mach-tegra/Makefile
> +++ b/arch/arm/mach-tegra/Makefile
> @@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pm-tegra20.o
>  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-tegra30.o
>  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= pm-tegra30.o
>  obj-$(CONFIG_SMP)			+= platsmp.o
> -obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
> +obj-y					+= hotplug.o
>  
>  obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= sleep-tegra30.o
>  obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= pm-tegra30.o
> diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
> index e6911a14c096..c8a63719a143 100644
> --- a/arch/arm/mach-tegra/platsmp.c
> +++ b/arch/arm/mach-tegra/platsmp.c
> @@ -183,8 +183,6 @@ const struct smp_operations tegra_smp_ops __initconst = {
>  	.smp_prepare_cpus	= tegra_smp_prepare_cpus,
>  	.smp_secondary_init	= tegra_secondary_init,
>  	.smp_boot_secondary	= tegra_boot_secondary,
> -#ifdef CONFIG_HOTPLUG_CPU
>  	.cpu_kill		= tegra_cpu_kill,
>  	.cpu_die		= tegra_cpu_die,
> -#endif
>  };
> diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
> index 6aaacb5757e1..f9c9bce9e15d 100644
> --- a/arch/arm/mach-tegra/pm.c
> +++ b/arch/arm/mach-tegra/pm.c
> @@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void)
>  	spin_unlock(&tegra_lp2_lock);
>  }
>  
> -bool tegra_set_cpu_in_lp2(void)
> +void tegra_set_cpu_in_lp2(void)
>  {
>  	int phy_cpu_id = cpu_logical_map(smp_processor_id());
> -	bool last_cpu = false;
> -	cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
>  	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
>  
>  	spin_lock(&tegra_lp2_lock);
> @@ -135,11 +133,7 @@ bool tegra_set_cpu_in_lp2(void)
>  	BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
>  	*cpu_in_lp2 |= BIT(phy_cpu_id);
>  
> -	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
> -		last_cpu = true;
> -
>  	spin_unlock(&tegra_lp2_lock);
> -	return last_cpu;
>  }

I think that the commit message should describe what is going on here or
this should be a separate change.

>  
>  static int tegra_sleep_cpu(unsigned long v2p)
> @@ -195,14 +189,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
>  	tegra_pmc_enter_suspend_mode(mode);
>  }
>  
> -void tegra_idle_lp2_last(void)
> +int tegra_idle_lp2_last(void)
>  {
> +	int err;
> +
>  	tegra_pm_set(TEGRA_SUSPEND_LP2);
>  
>  	cpu_cluster_pm_enter();
>  	suspend_cpu_complex();
>  
> -	cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
> +	err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
>  
>  	/*
>  	 * Resume L2 cache if it wasn't re-enabled early during resume,
> @@ -214,6 +210,8 @@ void tegra_idle_lp2_last(void)
>  
>  	restore_cpu_complex();
>  	cpu_cluster_pm_exit();
> +
> +	return err;
>  }
>  
>  enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
> diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
> index 1e51a9b636eb..81525f5f4a44 100644
> --- a/arch/arm/mach-tegra/pm.h
> +++ b/arch/arm/mach-tegra/pm.h
> @@ -23,9 +23,6 @@ void tegra20_sleep_core_init(void);
>  void tegra30_lp1_iram_hook(void);
>  void tegra30_sleep_core_init(void);
>  
> -void tegra_clear_cpu_in_lp2(void);
> -bool tegra_set_cpu_in_lp2(void);
> -void tegra_idle_lp2_last(void);
>  extern void (*tegra_tear_down_cpu)(void);
>  
>  #ifdef CONFIG_PM_SLEEP
> diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
> index d219872b7546..0d9956e9a8ea 100644
> --- a/arch/arm/mach-tegra/sleep.h
> +++ b/arch/arm/mach-tegra/sleep.h
> @@ -124,7 +124,6 @@ void tegra30_hotplug_shutdown(void);
>  #endif
>  
>  void tegra20_tear_down_cpu(void);
> -int tegra30_sleep_cpu_secondary_finish(unsigned long);
>  void tegra30_tear_down_cpu(void);
>  
>  #endif
> diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
> index b8aef62cc3f5..cf0f2cb5e109 100644
> --- a/include/linux/clk/tegra.h
> +++ b/include/linux/clk/tegra.h
> @@ -108,6 +108,19 @@ static inline void tegra_cpu_clock_resume(void)
>  
>  	tegra_cpu_car_ops->resume();
>  }
> +#else
> +static inline bool tegra_cpu_rail_off_ready(void)
> +{
> +	return false;
> +}
> +
> +static inline void tegra_cpu_clock_suspend(void)
> +{
> +}
> +
> +static inline void tegra_cpu_clock_resume(void)
> +{
> +}
>  #endif
>  
>  extern void tegra210_xusb_pll_hw_control_enable(void);
> diff --git a/include/soc/tegra/pm.h b/include/soc/tegra/pm.h
> index 951fcd738d55..fa18c2df5028 100644
> --- a/include/soc/tegra/pm.h
> +++ b/include/soc/tegra/pm.h
> @@ -20,6 +20,12 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
>  
>  /* low-level resume entry point */
>  void tegra_resume(void);
> +
> +int tegra30_sleep_cpu_secondary_finish(unsigned long arg);
> +void tegra_clear_cpu_in_lp2(void);
> +void tegra_set_cpu_in_lp2(void);
> +int tegra_idle_lp2_last(void);
> +void tegra_cpu_die(unsigned int cpu);
>  #else
>  static inline enum tegra_suspend_mode
>  tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
> @@ -30,6 +36,28 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
>  static inline void tegra_resume(void)
>  {
>  }
> +
> +static inline int tegra30_sleep_cpu_secondary_finish(unsigned long arg)
> +{
> +	return -1;
> +}

-ENOTSUPP?

Jon

-- 
nvpublic

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 2/6] ARM: tegra: Expose functions required for cpuidle driver
@ 2019-07-11 12:42     ` Jon Hunter
  0 siblings, 0 replies; 35+ messages in thread
From: Jon Hunter @ 2019-07-11 12:42 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm


On 11/07/2019 04:13, Dmitry Osipenko wrote:
> The upcoming unified CPUIDLE driver will be added to the drivers/cpuidle/
> directory and it will require all these Tegra PM-core functions.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/mach-tegra/Makefile  |  2 +-
>  arch/arm/mach-tegra/platsmp.c |  2 --
>  arch/arm/mach-tegra/pm.c      | 16 +++++++---------
>  arch/arm/mach-tegra/pm.h      |  3 ---
>  arch/arm/mach-tegra/sleep.h   |  1 -
>  include/linux/clk/tegra.h     | 13 +++++++++++++
>  include/soc/tegra/pm.h        | 28 ++++++++++++++++++++++++++++
>  7 files changed, 49 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
> index 5d93a0b36866..27bd5d9865e3 100644
> --- a/arch/arm/mach-tegra/Makefile
> +++ b/arch/arm/mach-tegra/Makefile
> @@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pm-tegra20.o
>  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-tegra30.o
>  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= pm-tegra30.o
>  obj-$(CONFIG_SMP)			+= platsmp.o
> -obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
> +obj-y					+= hotplug.o
>  
>  obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= sleep-tegra30.o
>  obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= pm-tegra30.o
> diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
> index e6911a14c096..c8a63719a143 100644
> --- a/arch/arm/mach-tegra/platsmp.c
> +++ b/arch/arm/mach-tegra/platsmp.c
> @@ -183,8 +183,6 @@ const struct smp_operations tegra_smp_ops __initconst = {
>  	.smp_prepare_cpus	= tegra_smp_prepare_cpus,
>  	.smp_secondary_init	= tegra_secondary_init,
>  	.smp_boot_secondary	= tegra_boot_secondary,
> -#ifdef CONFIG_HOTPLUG_CPU
>  	.cpu_kill		= tegra_cpu_kill,
>  	.cpu_die		= tegra_cpu_die,
> -#endif
>  };
> diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
> index 6aaacb5757e1..f9c9bce9e15d 100644
> --- a/arch/arm/mach-tegra/pm.c
> +++ b/arch/arm/mach-tegra/pm.c
> @@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void)
>  	spin_unlock(&tegra_lp2_lock);
>  }
>  
> -bool tegra_set_cpu_in_lp2(void)
> +void tegra_set_cpu_in_lp2(void)
>  {
>  	int phy_cpu_id = cpu_logical_map(smp_processor_id());
> -	bool last_cpu = false;
> -	cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
>  	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
>  
>  	spin_lock(&tegra_lp2_lock);
> @@ -135,11 +133,7 @@ bool tegra_set_cpu_in_lp2(void)
>  	BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
>  	*cpu_in_lp2 |= BIT(phy_cpu_id);
>  
> -	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
> -		last_cpu = true;
> -
>  	spin_unlock(&tegra_lp2_lock);
> -	return last_cpu;
>  }

I think that the commit message should describe what is going on here or
this should be a separate change.

>  
>  static int tegra_sleep_cpu(unsigned long v2p)
> @@ -195,14 +189,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
>  	tegra_pmc_enter_suspend_mode(mode);
>  }
>  
> -void tegra_idle_lp2_last(void)
> +int tegra_idle_lp2_last(void)
>  {
> +	int err;
> +
>  	tegra_pm_set(TEGRA_SUSPEND_LP2);
>  
>  	cpu_cluster_pm_enter();
>  	suspend_cpu_complex();
>  
> -	cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
> +	err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
>  
>  	/*
>  	 * Resume L2 cache if it wasn't re-enabled early during resume,
> @@ -214,6 +210,8 @@ void tegra_idle_lp2_last(void)
>  
>  	restore_cpu_complex();
>  	cpu_cluster_pm_exit();
> +
> +	return err;
>  }
>  
>  enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
> diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
> index 1e51a9b636eb..81525f5f4a44 100644
> --- a/arch/arm/mach-tegra/pm.h
> +++ b/arch/arm/mach-tegra/pm.h
> @@ -23,9 +23,6 @@ void tegra20_sleep_core_init(void);
>  void tegra30_lp1_iram_hook(void);
>  void tegra30_sleep_core_init(void);
>  
> -void tegra_clear_cpu_in_lp2(void);
> -bool tegra_set_cpu_in_lp2(void);
> -void tegra_idle_lp2_last(void);
>  extern void (*tegra_tear_down_cpu)(void);
>  
>  #ifdef CONFIG_PM_SLEEP
> diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
> index d219872b7546..0d9956e9a8ea 100644
> --- a/arch/arm/mach-tegra/sleep.h
> +++ b/arch/arm/mach-tegra/sleep.h
> @@ -124,7 +124,6 @@ void tegra30_hotplug_shutdown(void);
>  #endif
>  
>  void tegra20_tear_down_cpu(void);
> -int tegra30_sleep_cpu_secondary_finish(unsigned long);
>  void tegra30_tear_down_cpu(void);
>  
>  #endif
> diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
> index b8aef62cc3f5..cf0f2cb5e109 100644
> --- a/include/linux/clk/tegra.h
> +++ b/include/linux/clk/tegra.h
> @@ -108,6 +108,19 @@ static inline void tegra_cpu_clock_resume(void)
>  
>  	tegra_cpu_car_ops->resume();
>  }
> +#else
> +static inline bool tegra_cpu_rail_off_ready(void)
> +{
> +	return false;
> +}
> +
> +static inline void tegra_cpu_clock_suspend(void)
> +{
> +}
> +
> +static inline void tegra_cpu_clock_resume(void)
> +{
> +}
>  #endif
>  
>  extern void tegra210_xusb_pll_hw_control_enable(void);
> diff --git a/include/soc/tegra/pm.h b/include/soc/tegra/pm.h
> index 951fcd738d55..fa18c2df5028 100644
> --- a/include/soc/tegra/pm.h
> +++ b/include/soc/tegra/pm.h
> @@ -20,6 +20,12 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
>  
>  /* low-level resume entry point */
>  void tegra_resume(void);
> +
> +int tegra30_sleep_cpu_secondary_finish(unsigned long arg);
> +void tegra_clear_cpu_in_lp2(void);
> +void tegra_set_cpu_in_lp2(void);
> +int tegra_idle_lp2_last(void);
> +void tegra_cpu_die(unsigned int cpu);
>  #else
>  static inline enum tegra_suspend_mode
>  tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
> @@ -30,6 +36,28 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
>  static inline void tegra_resume(void)
>  {
>  }
> +
> +static inline int tegra30_sleep_cpu_secondary_finish(unsigned long arg)
> +{
> +	return -1;
> +}

-ENOTSUPP?

Jon

-- 
nvpublic

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
  2019-07-11  9:26     ` Jon Hunter
@ 2019-07-11 17:03       ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11 17:03 UTC (permalink / raw)
  To: Jon Hunter, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

11.07.2019 12:26, Jon Hunter пишет:
> 
> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>> Remove the old drivers to replace them cleanly with a new one later on.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  arch/arm/mach-tegra/Makefile           |  13 --
>>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>>  arch/arm/mach-tegra/irq.c              |  18 ---
>>  arch/arm/mach-tegra/irq.h              |  11 --
>>  arch/arm/mach-tegra/pm.c               |   7 -
>>  arch/arm/mach-tegra/pm.h               |   1 -
>>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>>  arch/arm/mach-tegra/reset.h            |   9 +-
>>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>>  arch/arm/mach-tegra/sleep.h            |  12 --
>>  arch/arm/mach-tegra/tegra.c            |   3 -
>>  drivers/soc/tegra/Kconfig              |   1 -
>>  include/soc/tegra/cpuidle.h            |   4 -
>>  17 files changed, 5 insertions(+), 779 deletions(-)
>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>>  delete mode 100644 arch/arm/mach-tegra/irq.h
> 
> By removing all the above, it is really hard to review the diff. Is
> there any way you could first consolidate the cpuidle drivers into say
> the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
> drivers/cpuidle?

I'm afraid that it will make reviewing even more difficult because
everything that is removed here is not returned in the further patches.
The new driver is based on the older ones, but I wrote it from scratch
and it's not only looks different, but also works a bit different as you
may see.

Could you please clarify what exactly makes it hard to review? The diff
looks pretty clean to me, while squashing everything into existing
driver should be quite a mess.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
@ 2019-07-11 17:03       ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11 17:03 UTC (permalink / raw)
  To: Jon Hunter, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

11.07.2019 12:26, Jon Hunter пишет:
> 
> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>> Remove the old drivers to replace them cleanly with a new one later on.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  arch/arm/mach-tegra/Makefile           |  13 --
>>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>>  arch/arm/mach-tegra/irq.c              |  18 ---
>>  arch/arm/mach-tegra/irq.h              |  11 --
>>  arch/arm/mach-tegra/pm.c               |   7 -
>>  arch/arm/mach-tegra/pm.h               |   1 -
>>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>>  arch/arm/mach-tegra/reset.h            |   9 +-
>>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>>  arch/arm/mach-tegra/sleep.h            |  12 --
>>  arch/arm/mach-tegra/tegra.c            |   3 -
>>  drivers/soc/tegra/Kconfig              |   1 -
>>  include/soc/tegra/cpuidle.h            |   4 -
>>  17 files changed, 5 insertions(+), 779 deletions(-)
>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>>  delete mode 100644 arch/arm/mach-tegra/irq.h
> 
> By removing all the above, it is really hard to review the diff. Is
> there any way you could first consolidate the cpuidle drivers into say
> the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
> drivers/cpuidle?

I'm afraid that it will make reviewing even more difficult because
everything that is removed here is not returned in the further patches.
The new driver is based on the older ones, but I wrote it from scratch
and it's not only looks different, but also works a bit different as you
may see.

Could you please clarify what exactly makes it hard to review? The diff
looks pretty clean to me, while squashing everything into existing
driver should be quite a mess.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 2/6] ARM: tegra: Expose functions required for cpuidle driver
  2019-07-11 12:42     ` Jon Hunter
@ 2019-07-11 17:25       ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11 17:25 UTC (permalink / raw)
  To: Jon Hunter, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

11.07.2019 15:42, Jon Hunter пишет:
> 
> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>> The upcoming unified CPUIDLE driver will be added to the drivers/cpuidle/
>> directory and it will require all these Tegra PM-core functions.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  arch/arm/mach-tegra/Makefile  |  2 +-
>>  arch/arm/mach-tegra/platsmp.c |  2 --
>>  arch/arm/mach-tegra/pm.c      | 16 +++++++---------
>>  arch/arm/mach-tegra/pm.h      |  3 ---
>>  arch/arm/mach-tegra/sleep.h   |  1 -
>>  include/linux/clk/tegra.h     | 13 +++++++++++++
>>  include/soc/tegra/pm.h        | 28 ++++++++++++++++++++++++++++
>>  7 files changed, 49 insertions(+), 16 deletions(-)
>>
>> diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
>> index 5d93a0b36866..27bd5d9865e3 100644
>> --- a/arch/arm/mach-tegra/Makefile
>> +++ b/arch/arm/mach-tegra/Makefile
>> @@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pm-tegra20.o
>>  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-tegra30.o
>>  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= pm-tegra30.o
>>  obj-$(CONFIG_SMP)			+= platsmp.o
>> -obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
>> +obj-y					+= hotplug.o
>>  
>>  obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= sleep-tegra30.o
>>  obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= pm-tegra30.o
>> diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
>> index e6911a14c096..c8a63719a143 100644
>> --- a/arch/arm/mach-tegra/platsmp.c
>> +++ b/arch/arm/mach-tegra/platsmp.c
>> @@ -183,8 +183,6 @@ const struct smp_operations tegra_smp_ops __initconst = {
>>  	.smp_prepare_cpus	= tegra_smp_prepare_cpus,
>>  	.smp_secondary_init	= tegra_secondary_init,
>>  	.smp_boot_secondary	= tegra_boot_secondary,
>> -#ifdef CONFIG_HOTPLUG_CPU
>>  	.cpu_kill		= tegra_cpu_kill,
>>  	.cpu_die		= tegra_cpu_die,
>> -#endif
>>  };
>> diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
>> index 6aaacb5757e1..f9c9bce9e15d 100644
>> --- a/arch/arm/mach-tegra/pm.c
>> +++ b/arch/arm/mach-tegra/pm.c
>> @@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void)
>>  	spin_unlock(&tegra_lp2_lock);
>>  }
>>  
>> -bool tegra_set_cpu_in_lp2(void)
>> +void tegra_set_cpu_in_lp2(void)
>>  {
>>  	int phy_cpu_id = cpu_logical_map(smp_processor_id());
>> -	bool last_cpu = false;
>> -	cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
>>  	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
>>  
>>  	spin_lock(&tegra_lp2_lock);
>> @@ -135,11 +133,7 @@ bool tegra_set_cpu_in_lp2(void)
>>  	BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
>>  	*cpu_in_lp2 |= BIT(phy_cpu_id);
>>  
>> -	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
>> -		last_cpu = true;
>> -
>>  	spin_unlock(&tegra_lp2_lock);
>> -	return last_cpu;
>>  }
> 
> I think that the commit message should describe what is going on here or
> this should be a separate change.

Indeed, it could be not very obvious what's going on here without a
thorough review. I'll factor out all these minor changes into separate
commits.

In particular there is no need to know whether CPU is the "last_cpu" for
the new driver because CPU0 is always the "last" since it awaits for the
secondaries in the coupled state.

>>  static int tegra_sleep_cpu(unsigned long v2p)
>> @@ -195,14 +189,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
>>  	tegra_pmc_enter_suspend_mode(mode);
>>  }
>>  
>> -void tegra_idle_lp2_last(void)
>> +int tegra_idle_lp2_last(void)
>>  {
>> +	int err;
>> +
>>  	tegra_pm_set(TEGRA_SUSPEND_LP2);
>>  
>>  	cpu_cluster_pm_enter();
>>  	suspend_cpu_complex();
>>  
>> -	cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
>> +	err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
>>  
>>  	/*
>>  	 * Resume L2 cache if it wasn't re-enabled early during resume,
>> @@ -214,6 +210,8 @@ void tegra_idle_lp2_last(void)
>>  
>>  	restore_cpu_complex();
>>  	cpu_cluster_pm_exit();
>> +
>> +	return err;
>>  }
>>  
>>  enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
>> diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
>> index 1e51a9b636eb..81525f5f4a44 100644
>> --- a/arch/arm/mach-tegra/pm.h
>> +++ b/arch/arm/mach-tegra/pm.h
>> @@ -23,9 +23,6 @@ void tegra20_sleep_core_init(void);
>>  void tegra30_lp1_iram_hook(void);
>>  void tegra30_sleep_core_init(void);
>>  
>> -void tegra_clear_cpu_in_lp2(void);
>> -bool tegra_set_cpu_in_lp2(void);
>> -void tegra_idle_lp2_last(void);
>>  extern void (*tegra_tear_down_cpu)(void);
>>  
>>  #ifdef CONFIG_PM_SLEEP
>> diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
>> index d219872b7546..0d9956e9a8ea 100644
>> --- a/arch/arm/mach-tegra/sleep.h
>> +++ b/arch/arm/mach-tegra/sleep.h
>> @@ -124,7 +124,6 @@ void tegra30_hotplug_shutdown(void);
>>  #endif
>>  
>>  void tegra20_tear_down_cpu(void);
>> -int tegra30_sleep_cpu_secondary_finish(unsigned long);
>>  void tegra30_tear_down_cpu(void);
>>  
>>  #endif
>> diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
>> index b8aef62cc3f5..cf0f2cb5e109 100644
>> --- a/include/linux/clk/tegra.h
>> +++ b/include/linux/clk/tegra.h
>> @@ -108,6 +108,19 @@ static inline void tegra_cpu_clock_resume(void)
>>  
>>  	tegra_cpu_car_ops->resume();
>>  }
>> +#else
>> +static inline bool tegra_cpu_rail_off_ready(void)
>> +{
>> +	return false;
>> +}
>> +
>> +static inline void tegra_cpu_clock_suspend(void)
>> +{
>> +}
>> +
>> +static inline void tegra_cpu_clock_resume(void)
>> +{
>> +}
>>  #endif
>>  
>>  extern void tegra210_xusb_pll_hw_control_enable(void);
>> diff --git a/include/soc/tegra/pm.h b/include/soc/tegra/pm.h
>> index 951fcd738d55..fa18c2df5028 100644
>> --- a/include/soc/tegra/pm.h
>> +++ b/include/soc/tegra/pm.h
>> @@ -20,6 +20,12 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
>>  
>>  /* low-level resume entry point */
>>  void tegra_resume(void);
>> +
>> +int tegra30_sleep_cpu_secondary_finish(unsigned long arg);
>> +void tegra_clear_cpu_in_lp2(void);
>> +void tegra_set_cpu_in_lp2(void);
>> +int tegra_idle_lp2_last(void);
>> +void tegra_cpu_die(unsigned int cpu);
>>  #else
>>  static inline enum tegra_suspend_mode
>>  tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
>> @@ -30,6 +36,28 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
>>  static inline void tegra_resume(void)
>>  {
>>  }
>> +
>> +static inline int tegra30_sleep_cpu_secondary_finish(unsigned long arg)
>> +{
>> +	return -1;
>> +}
> 
> -ENOTSUPP?

Good point, thanks!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 2/6] ARM: tegra: Expose functions required for cpuidle driver
@ 2019-07-11 17:25       ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11 17:25 UTC (permalink / raw)
  To: Jon Hunter, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

11.07.2019 15:42, Jon Hunter пишет:
> 
> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>> The upcoming unified CPUIDLE driver will be added to the drivers/cpuidle/
>> directory and it will require all these Tegra PM-core functions.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  arch/arm/mach-tegra/Makefile  |  2 +-
>>  arch/arm/mach-tegra/platsmp.c |  2 --
>>  arch/arm/mach-tegra/pm.c      | 16 +++++++---------
>>  arch/arm/mach-tegra/pm.h      |  3 ---
>>  arch/arm/mach-tegra/sleep.h   |  1 -
>>  include/linux/clk/tegra.h     | 13 +++++++++++++
>>  include/soc/tegra/pm.h        | 28 ++++++++++++++++++++++++++++
>>  7 files changed, 49 insertions(+), 16 deletions(-)
>>
>> diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
>> index 5d93a0b36866..27bd5d9865e3 100644
>> --- a/arch/arm/mach-tegra/Makefile
>> +++ b/arch/arm/mach-tegra/Makefile
>> @@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pm-tegra20.o
>>  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= sleep-tegra30.o
>>  obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= pm-tegra30.o
>>  obj-$(CONFIG_SMP)			+= platsmp.o
>> -obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
>> +obj-y					+= hotplug.o
>>  
>>  obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= sleep-tegra30.o
>>  obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= pm-tegra30.o
>> diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
>> index e6911a14c096..c8a63719a143 100644
>> --- a/arch/arm/mach-tegra/platsmp.c
>> +++ b/arch/arm/mach-tegra/platsmp.c
>> @@ -183,8 +183,6 @@ const struct smp_operations tegra_smp_ops __initconst = {
>>  	.smp_prepare_cpus	= tegra_smp_prepare_cpus,
>>  	.smp_secondary_init	= tegra_secondary_init,
>>  	.smp_boot_secondary	= tegra_boot_secondary,
>> -#ifdef CONFIG_HOTPLUG_CPU
>>  	.cpu_kill		= tegra_cpu_kill,
>>  	.cpu_die		= tegra_cpu_die,
>> -#endif
>>  };
>> diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
>> index 6aaacb5757e1..f9c9bce9e15d 100644
>> --- a/arch/arm/mach-tegra/pm.c
>> +++ b/arch/arm/mach-tegra/pm.c
>> @@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void)
>>  	spin_unlock(&tegra_lp2_lock);
>>  }
>>  
>> -bool tegra_set_cpu_in_lp2(void)
>> +void tegra_set_cpu_in_lp2(void)
>>  {
>>  	int phy_cpu_id = cpu_logical_map(smp_processor_id());
>> -	bool last_cpu = false;
>> -	cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
>>  	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
>>  
>>  	spin_lock(&tegra_lp2_lock);
>> @@ -135,11 +133,7 @@ bool tegra_set_cpu_in_lp2(void)
>>  	BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id)));
>>  	*cpu_in_lp2 |= BIT(phy_cpu_id);
>>  
>> -	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
>> -		last_cpu = true;
>> -
>>  	spin_unlock(&tegra_lp2_lock);
>> -	return last_cpu;
>>  }
> 
> I think that the commit message should describe what is going on here or
> this should be a separate change.

Indeed, it could be not very obvious what's going on here without a
thorough review. I'll factor out all these minor changes into separate
commits.

In particular there is no need to know whether CPU is the "last_cpu" for
the new driver because CPU0 is always the "last" since it awaits for the
secondaries in the coupled state.

>>  static int tegra_sleep_cpu(unsigned long v2p)
>> @@ -195,14 +189,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
>>  	tegra_pmc_enter_suspend_mode(mode);
>>  }
>>  
>> -void tegra_idle_lp2_last(void)
>> +int tegra_idle_lp2_last(void)
>>  {
>> +	int err;
>> +
>>  	tegra_pm_set(TEGRA_SUSPEND_LP2);
>>  
>>  	cpu_cluster_pm_enter();
>>  	suspend_cpu_complex();
>>  
>> -	cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
>> +	err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
>>  
>>  	/*
>>  	 * Resume L2 cache if it wasn't re-enabled early during resume,
>> @@ -214,6 +210,8 @@ void tegra_idle_lp2_last(void)
>>  
>>  	restore_cpu_complex();
>>  	cpu_cluster_pm_exit();
>> +
>> +	return err;
>>  }
>>  
>>  enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
>> diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
>> index 1e51a9b636eb..81525f5f4a44 100644
>> --- a/arch/arm/mach-tegra/pm.h
>> +++ b/arch/arm/mach-tegra/pm.h
>> @@ -23,9 +23,6 @@ void tegra20_sleep_core_init(void);
>>  void tegra30_lp1_iram_hook(void);
>>  void tegra30_sleep_core_init(void);
>>  
>> -void tegra_clear_cpu_in_lp2(void);
>> -bool tegra_set_cpu_in_lp2(void);
>> -void tegra_idle_lp2_last(void);
>>  extern void (*tegra_tear_down_cpu)(void);
>>  
>>  #ifdef CONFIG_PM_SLEEP
>> diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
>> index d219872b7546..0d9956e9a8ea 100644
>> --- a/arch/arm/mach-tegra/sleep.h
>> +++ b/arch/arm/mach-tegra/sleep.h
>> @@ -124,7 +124,6 @@ void tegra30_hotplug_shutdown(void);
>>  #endif
>>  
>>  void tegra20_tear_down_cpu(void);
>> -int tegra30_sleep_cpu_secondary_finish(unsigned long);
>>  void tegra30_tear_down_cpu(void);
>>  
>>  #endif
>> diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
>> index b8aef62cc3f5..cf0f2cb5e109 100644
>> --- a/include/linux/clk/tegra.h
>> +++ b/include/linux/clk/tegra.h
>> @@ -108,6 +108,19 @@ static inline void tegra_cpu_clock_resume(void)
>>  
>>  	tegra_cpu_car_ops->resume();
>>  }
>> +#else
>> +static inline bool tegra_cpu_rail_off_ready(void)
>> +{
>> +	return false;
>> +}
>> +
>> +static inline void tegra_cpu_clock_suspend(void)
>> +{
>> +}
>> +
>> +static inline void tegra_cpu_clock_resume(void)
>> +{
>> +}
>>  #endif
>>  
>>  extern void tegra210_xusb_pll_hw_control_enable(void);
>> diff --git a/include/soc/tegra/pm.h b/include/soc/tegra/pm.h
>> index 951fcd738d55..fa18c2df5028 100644
>> --- a/include/soc/tegra/pm.h
>> +++ b/include/soc/tegra/pm.h
>> @@ -20,6 +20,12 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
>>  
>>  /* low-level resume entry point */
>>  void tegra_resume(void);
>> +
>> +int tegra30_sleep_cpu_secondary_finish(unsigned long arg);
>> +void tegra_clear_cpu_in_lp2(void);
>> +void tegra_set_cpu_in_lp2(void);
>> +int tegra_idle_lp2_last(void);
>> +void tegra_cpu_die(unsigned int cpu);
>>  #else
>>  static inline enum tegra_suspend_mode
>>  tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
>> @@ -30,6 +36,28 @@ tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
>>  static inline void tegra_resume(void)
>>  {
>>  }
>> +
>> +static inline int tegra30_sleep_cpu_secondary_finish(unsigned long arg)
>> +{
>> +	return -1;
>> +}
> 
> -ENOTSUPP?

Good point, thanks!

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 3/6] cpuidle: Add unified driver for NVIDIA Tegra SoCs
  2019-07-11  3:13   ` Dmitry Osipenko
@ 2019-07-11 18:35     ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11 18:35 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

11.07.2019 6:13, Dmitry Osipenko пишет:
> The new driver is based on the old CPU Idle drivers that are removed now
> from arm/arch/mach-tegra/ directory. Those removed drivers were reworked
> and squashed into a single unified driver that covers multiple hardware
> generations, starting from Tegra20 and ending with Tegra124.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/mach-tegra/tegra.c     |   4 +
>  drivers/cpuidle/Kconfig.arm     |   8 +
>  drivers/cpuidle/Makefile        |   1 +
>  drivers/cpuidle/cpuidle-tegra.c | 304 ++++++++++++++++++++++++++++++++
>  include/soc/tegra/cpuidle.h     |   4 +
>  5 files changed, 321 insertions(+)
>  create mode 100644 drivers/cpuidle/cpuidle-tegra.c
> 
> diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
> index d9237769a37c..f1ce2857a251 100644
> --- a/arch/arm/mach-tegra/tegra.c
> +++ b/arch/arm/mach-tegra/tegra.c
> @@ -36,6 +36,7 @@
>  #include <asm/mach/arch.h>
>  #include <asm/mach/time.h>
>  #include <asm/mach-types.h>
> +#include <asm/psci.h>
>  #include <asm/setup.h>
>  
>  #include "board.h"
> @@ -92,6 +93,9 @@ static void __init tegra_dt_init_late(void)
>  	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
>  	    of_machine_is_compatible("nvidia,tegra20"))
>  		platform_device_register_simple("tegra20-cpufreq", -1, NULL, 0);
> +
> +	if (IS_ENABLED(CONFIG_ARM_TEGRA_CPUIDLE) && !psci_smp_available())
> +		platform_device_register_simple("tegra-cpuidle", -1, NULL, 0);
>  }
>  
>  static const char * const tegra_dt_board_compat[] = {
> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> index 48cb3d4bb7d1..d90861361f1d 100644
> --- a/drivers/cpuidle/Kconfig.arm
> +++ b/drivers/cpuidle/Kconfig.arm
> @@ -76,3 +76,11 @@ config ARM_MVEBU_V7_CPUIDLE
>  	depends on ARCH_MVEBU && !ARM64
>  	help
>  	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
> +
> +config ARM_TEGRA_CPUIDLE
> +	bool "CPU Idle Driver for NVIDIA Tegra SoCs"
> +	depends on ARCH_TEGRA && !ARM64
> +	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
> +	select ARM_CPU_SUSPEND
> +	help
> +	  Select this to enable cpuidle for NVIDIA Tegra20/30/114/124 SoCs.
> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> index 9d7176cee3d3..470d17fa8746 100644
> --- a/drivers/cpuidle/Makefile
> +++ b/drivers/cpuidle/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
>  obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
>  obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
>  obj-$(CONFIG_ARM_CPUIDLE)		+= cpuidle-arm.o
> +obj-$(CONFIG_ARM_TEGRA_CPUIDLE)		+= cpuidle-tegra.o
>  
>  ###############################################################################
>  # MIPS drivers
> diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c
> new file mode 100644
> index 000000000000..54974cd2255f
> --- /dev/null
> +++ b/drivers/cpuidle/cpuidle-tegra.c
> @@ -0,0 +1,304 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * CPU idle driver for Tegra CPUs
> + *
> + * Copyright (c) 2010-2013, 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>
> + *
> + * Tegra20/124 driver unification by Dmitry Osipenko <digetx@gmail.com>
> + */
> +
> +#include <linux/cpuidle.h>
> +#include <linux/cpumask.h>
> +#include <linux/cpu_pm.h>
> +#include <linux/errno.h>
> +#include <linux/ktime.h>
> +#include <linux/platform_device.h>
> +#include <linux/types.h>
> +
> +#include <linux/clk/tegra.h>
> +#include <linux/firmware/trusted_foundations.h>
> +
> +#include <soc/tegra/cpuidle.h>
> +#include <soc/tegra/flowctrl.h>
> +#include <soc/tegra/fuse.h>
> +#include <soc/tegra/pm.h>
> +
> +#include <asm/cpuidle.h>
> +#include <asm/firmware.h>
> +#include <asm/smp_plat.h>
> +#include <asm/suspend.h>
> +
> +#define TEGRA_C1		0
> +#define TEGRA_C7		1
> +#define TEGRA_CC6		2
> +
> +static atomic_t tegra_idle_barrier;
> +
> +static inline bool tegra_cpuidle_using_firmware(void)
> +{
> +	return firmware_ops->prepare_idle && firmware_ops->do_idle;
> +}
> +
> +static int tegra_shutdown_secondary_cpu(unsigned long cpu)
> +{
> +	tegra_cpu_die(cpu);
> +
> +	return -EINVAL;
> +}
> +
> +static int tegra_await_secondary_cpus_shutdown(void)
> +{
> +	ktime_t timeout = ktime_add_ms(ktime_get(), 1);
> +
> +	/*
> +	 * The boot CPU shall await for the secondaries shutdown in order
> +	 * to power-off CPU's cluster safely.
> +	 */
> +	do {
> +		if (tegra_cpu_rail_off_ready())
> +			return 0;
> +
> +	} while (ktime_compare(ktime_get(), timeout) < 0);
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static void tegra_wake_up_secondary_cpus(void)
> +{
> +	unsigned int cpu, lcpu;
> +
> +	for_each_cpu(lcpu, cpu_online_mask) {
> +		cpu = cpu_logical_map(lcpu);
> +
> +		if (cpu > 0) {
> +			tegra_enable_cpu_clock(cpu);
> +			tegra_cpu_out_of_reset(cpu);
> +			flowctrl_write_cpu_halt(cpu, 0);
> +		}
> +	}
> +}
> +
> +static int tegra_cpuidle_cc6_enter(void)
> +{
> +	int err;
> +
> +	err = tegra_await_secondary_cpus_shutdown();
> +	if (err)
> +		return err;
> +
> +	err = tegra_idle_lp2_last();
> +
> +	tegra_wake_up_secondary_cpus();
> +
> +	return err;
> +}
> +
> +static int tegra_cpuidle_c7_enter(void)
> +{
> +	int err;
> +
> +	if (tegra_cpuidle_using_firmware()) {
> +		err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
> +		if (err)
> +			return err;
> +
> +		return call_firmware_op(do_idle, 0);
> +	}
> +
> +	return cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
> +}
> +
> +static int tegra_cpuidle_enter(struct cpuidle_device *dev,
> +			       int index, unsigned int cpu)
> +{
> +	int err;
> +
> +	local_fiq_disable();
> +	tegra_set_cpu_in_lp2();
> +	cpu_pm_enter();
> +
> +	switch (index) {
> +	case TEGRA_C7:
> +		err = tegra_cpuidle_c7_enter();
> +		break;
> +	case TEGRA_CC6:
> +		cpuidle_coupled_parallel_barrier(dev, &tegra_idle_barrier);

I realized that this is not very correct. We still need to do a proper
barrier with SGI checking in order to bail out if other CPU sent IPI
during of the awaiting for a coupled barrier to avoid the overhead of
unnecessary power-gating. Will correct that in the next revision.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 3/6] cpuidle: Add unified driver for NVIDIA Tegra SoCs
@ 2019-07-11 18:35     ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-11 18:35 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

11.07.2019 6:13, Dmitry Osipenko пишет:
> The new driver is based on the old CPU Idle drivers that are removed now
> from arm/arch/mach-tegra/ directory. Those removed drivers were reworked
> and squashed into a single unified driver that covers multiple hardware
> generations, starting from Tegra20 and ending with Tegra124.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/mach-tegra/tegra.c     |   4 +
>  drivers/cpuidle/Kconfig.arm     |   8 +
>  drivers/cpuidle/Makefile        |   1 +
>  drivers/cpuidle/cpuidle-tegra.c | 304 ++++++++++++++++++++++++++++++++
>  include/soc/tegra/cpuidle.h     |   4 +
>  5 files changed, 321 insertions(+)
>  create mode 100644 drivers/cpuidle/cpuidle-tegra.c
> 
> diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
> index d9237769a37c..f1ce2857a251 100644
> --- a/arch/arm/mach-tegra/tegra.c
> +++ b/arch/arm/mach-tegra/tegra.c
> @@ -36,6 +36,7 @@
>  #include <asm/mach/arch.h>
>  #include <asm/mach/time.h>
>  #include <asm/mach-types.h>
> +#include <asm/psci.h>
>  #include <asm/setup.h>
>  
>  #include "board.h"
> @@ -92,6 +93,9 @@ static void __init tegra_dt_init_late(void)
>  	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
>  	    of_machine_is_compatible("nvidia,tegra20"))
>  		platform_device_register_simple("tegra20-cpufreq", -1, NULL, 0);
> +
> +	if (IS_ENABLED(CONFIG_ARM_TEGRA_CPUIDLE) && !psci_smp_available())
> +		platform_device_register_simple("tegra-cpuidle", -1, NULL, 0);
>  }
>  
>  static const char * const tegra_dt_board_compat[] = {
> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> index 48cb3d4bb7d1..d90861361f1d 100644
> --- a/drivers/cpuidle/Kconfig.arm
> +++ b/drivers/cpuidle/Kconfig.arm
> @@ -76,3 +76,11 @@ config ARM_MVEBU_V7_CPUIDLE
>  	depends on ARCH_MVEBU && !ARM64
>  	help
>  	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
> +
> +config ARM_TEGRA_CPUIDLE
> +	bool "CPU Idle Driver for NVIDIA Tegra SoCs"
> +	depends on ARCH_TEGRA && !ARM64
> +	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
> +	select ARM_CPU_SUSPEND
> +	help
> +	  Select this to enable cpuidle for NVIDIA Tegra20/30/114/124 SoCs.
> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> index 9d7176cee3d3..470d17fa8746 100644
> --- a/drivers/cpuidle/Makefile
> +++ b/drivers/cpuidle/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
>  obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
>  obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
>  obj-$(CONFIG_ARM_CPUIDLE)		+= cpuidle-arm.o
> +obj-$(CONFIG_ARM_TEGRA_CPUIDLE)		+= cpuidle-tegra.o
>  
>  ###############################################################################
>  # MIPS drivers
> diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c
> new file mode 100644
> index 000000000000..54974cd2255f
> --- /dev/null
> +++ b/drivers/cpuidle/cpuidle-tegra.c
> @@ -0,0 +1,304 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * CPU idle driver for Tegra CPUs
> + *
> + * Copyright (c) 2010-2013, 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>
> + *
> + * Tegra20/124 driver unification by Dmitry Osipenko <digetx@gmail.com>
> + */
> +
> +#include <linux/cpuidle.h>
> +#include <linux/cpumask.h>
> +#include <linux/cpu_pm.h>
> +#include <linux/errno.h>
> +#include <linux/ktime.h>
> +#include <linux/platform_device.h>
> +#include <linux/types.h>
> +
> +#include <linux/clk/tegra.h>
> +#include <linux/firmware/trusted_foundations.h>
> +
> +#include <soc/tegra/cpuidle.h>
> +#include <soc/tegra/flowctrl.h>
> +#include <soc/tegra/fuse.h>
> +#include <soc/tegra/pm.h>
> +
> +#include <asm/cpuidle.h>
> +#include <asm/firmware.h>
> +#include <asm/smp_plat.h>
> +#include <asm/suspend.h>
> +
> +#define TEGRA_C1		0
> +#define TEGRA_C7		1
> +#define TEGRA_CC6		2
> +
> +static atomic_t tegra_idle_barrier;
> +
> +static inline bool tegra_cpuidle_using_firmware(void)
> +{
> +	return firmware_ops->prepare_idle && firmware_ops->do_idle;
> +}
> +
> +static int tegra_shutdown_secondary_cpu(unsigned long cpu)
> +{
> +	tegra_cpu_die(cpu);
> +
> +	return -EINVAL;
> +}
> +
> +static int tegra_await_secondary_cpus_shutdown(void)
> +{
> +	ktime_t timeout = ktime_add_ms(ktime_get(), 1);
> +
> +	/*
> +	 * The boot CPU shall await for the secondaries shutdown in order
> +	 * to power-off CPU's cluster safely.
> +	 */
> +	do {
> +		if (tegra_cpu_rail_off_ready())
> +			return 0;
> +
> +	} while (ktime_compare(ktime_get(), timeout) < 0);
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static void tegra_wake_up_secondary_cpus(void)
> +{
> +	unsigned int cpu, lcpu;
> +
> +	for_each_cpu(lcpu, cpu_online_mask) {
> +		cpu = cpu_logical_map(lcpu);
> +
> +		if (cpu > 0) {
> +			tegra_enable_cpu_clock(cpu);
> +			tegra_cpu_out_of_reset(cpu);
> +			flowctrl_write_cpu_halt(cpu, 0);
> +		}
> +	}
> +}
> +
> +static int tegra_cpuidle_cc6_enter(void)
> +{
> +	int err;
> +
> +	err = tegra_await_secondary_cpus_shutdown();
> +	if (err)
> +		return err;
> +
> +	err = tegra_idle_lp2_last();
> +
> +	tegra_wake_up_secondary_cpus();
> +
> +	return err;
> +}
> +
> +static int tegra_cpuidle_c7_enter(void)
> +{
> +	int err;
> +
> +	if (tegra_cpuidle_using_firmware()) {
> +		err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
> +		if (err)
> +			return err;
> +
> +		return call_firmware_op(do_idle, 0);
> +	}
> +
> +	return cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
> +}
> +
> +static int tegra_cpuidle_enter(struct cpuidle_device *dev,
> +			       int index, unsigned int cpu)
> +{
> +	int err;
> +
> +	local_fiq_disable();
> +	tegra_set_cpu_in_lp2();
> +	cpu_pm_enter();
> +
> +	switch (index) {
> +	case TEGRA_C7:
> +		err = tegra_cpuidle_c7_enter();
> +		break;
> +	case TEGRA_CC6:
> +		cpuidle_coupled_parallel_barrier(dev, &tegra_idle_barrier);

I realized that this is not very correct. We still need to do a proper
barrier with SGI checking in order to bail out if other CPU sent IPI
during of the awaiting for a coupled barrier to avoid the overhead of
unnecessary power-gating. Will correct that in the next revision.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
  2019-07-11 17:03       ` Dmitry Osipenko
  (?)
@ 2019-07-12  9:39         ` Jon Hunter
  -1 siblings, 0 replies; 35+ messages in thread
From: Jon Hunter @ 2019-07-12  9:39 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel


On 11/07/2019 18:03, Dmitry Osipenko wrote:
> 11.07.2019 12:26, Jon Hunter пишет:
>>
>> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>>> Remove the old drivers to replace them cleanly with a new one later on.
>>>
>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>> ---
>>>  arch/arm/mach-tegra/Makefile           |  13 --
>>>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>>>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>>>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>>>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>>>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>>>  arch/arm/mach-tegra/irq.c              |  18 ---
>>>  arch/arm/mach-tegra/irq.h              |  11 --
>>>  arch/arm/mach-tegra/pm.c               |   7 -
>>>  arch/arm/mach-tegra/pm.h               |   1 -
>>>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>>>  arch/arm/mach-tegra/reset.h            |   9 +-
>>>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>>>  arch/arm/mach-tegra/sleep.h            |  12 --
>>>  arch/arm/mach-tegra/tegra.c            |   3 -
>>>  drivers/soc/tegra/Kconfig              |   1 -
>>>  include/soc/tegra/cpuidle.h            |   4 -
>>>  17 files changed, 5 insertions(+), 779 deletions(-)
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>>>  delete mode 100644 arch/arm/mach-tegra/irq.h
>>
>> By removing all the above, it is really hard to review the diff. Is
>> there any way you could first consolidate the cpuidle drivers into say
>> the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
>> drivers/cpuidle?
> 
> I'm afraid that it will make reviewing even more difficult because
> everything that is removed here is not returned in the further patches.
> The new driver is based on the older ones, but I wrote it from scratch
> and it's not only looks different, but also works a bit different as you
> may see.
> 
> Could you please clarify what exactly makes it hard to review? The diff
> looks pretty clean to me, while squashing everything into existing
> driver should be quite a mess.

Ideally a patch should standalone and can be reviewed by itself.
However, to review this, we need to review patches 1, 2 and 3 at the
same time. So IMO it is not that convenient from a reviewers
perspective. Furthermore, patches 1 and 3 are large and so easy to miss
something.

Is there really no way to have a patch to combined the existing drivers,
then a patch to convert them into the newer rewritten version you have
implemented, then move the driver?

Jon

-- 
nvpublic

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
@ 2019-07-12  9:39         ` Jon Hunter
  0 siblings, 0 replies; 35+ messages in thread
From: Jon Hunter @ 2019-07-12  9:39 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel


On 11/07/2019 18:03, Dmitry Osipenko wrote:
> 11.07.2019 12:26, Jon Hunter пишет:
>>
>> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>>> Remove the old drivers to replace them cleanly with a new one later on.
>>>
>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>> ---
>>>  arch/arm/mach-tegra/Makefile           |  13 --
>>>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>>>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>>>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>>>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>>>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>>>  arch/arm/mach-tegra/irq.c              |  18 ---
>>>  arch/arm/mach-tegra/irq.h              |  11 --
>>>  arch/arm/mach-tegra/pm.c               |   7 -
>>>  arch/arm/mach-tegra/pm.h               |   1 -
>>>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>>>  arch/arm/mach-tegra/reset.h            |   9 +-
>>>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>>>  arch/arm/mach-tegra/sleep.h            |  12 --
>>>  arch/arm/mach-tegra/tegra.c            |   3 -
>>>  drivers/soc/tegra/Kconfig              |   1 -
>>>  include/soc/tegra/cpuidle.h            |   4 -
>>>  17 files changed, 5 insertions(+), 779 deletions(-)
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>>>  delete mode 100644 arch/arm/mach-tegra/irq.h
>>
>> By removing all the above, it is really hard to review the diff. Is
>> there any way you could first consolidate the cpuidle drivers into say
>> the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
>> drivers/cpuidle?
> 
> I'm afraid that it will make reviewing even more difficult because
> everything that is removed here is not returned in the further patches.
> The new driver is based on the older ones, but I wrote it from scratch
> and it's not only looks different, but also works a bit different as you
> may see.
> 
> Could you please clarify what exactly makes it hard to review? The diff
> looks pretty clean to me, while squashing everything into existing
> driver should be quite a mess.

Ideally a patch should standalone and can be reviewed by itself.
However, to review this, we need to review patches 1, 2 and 3 at the
same time. So IMO it is not that convenient from a reviewers
perspective. Furthermore, patches 1 and 3 are large and so easy to miss
something.

Is there really no way to have a patch to combined the existing drivers,
then a patch to convert them into the newer rewritten version you have
implemented, then move the driver?

Jon

-- 
nvpublic

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
@ 2019-07-12  9:39         ` Jon Hunter
  0 siblings, 0 replies; 35+ messages in thread
From: Jon Hunter @ 2019-07-12  9:39 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm


On 11/07/2019 18:03, Dmitry Osipenko wrote:
> 11.07.2019 12:26, Jon Hunter пишет:
>>
>> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>>> Remove the old drivers to replace them cleanly with a new one later on.
>>>
>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>> ---
>>>  arch/arm/mach-tegra/Makefile           |  13 --
>>>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>>>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>>>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>>>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>>>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>>>  arch/arm/mach-tegra/irq.c              |  18 ---
>>>  arch/arm/mach-tegra/irq.h              |  11 --
>>>  arch/arm/mach-tegra/pm.c               |   7 -
>>>  arch/arm/mach-tegra/pm.h               |   1 -
>>>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>>>  arch/arm/mach-tegra/reset.h            |   9 +-
>>>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>>>  arch/arm/mach-tegra/sleep.h            |  12 --
>>>  arch/arm/mach-tegra/tegra.c            |   3 -
>>>  drivers/soc/tegra/Kconfig              |   1 -
>>>  include/soc/tegra/cpuidle.h            |   4 -
>>>  17 files changed, 5 insertions(+), 779 deletions(-)
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>>>  delete mode 100644 arch/arm/mach-tegra/irq.h
>>
>> By removing all the above, it is really hard to review the diff. Is
>> there any way you could first consolidate the cpuidle drivers into say
>> the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
>> drivers/cpuidle?
> 
> I'm afraid that it will make reviewing even more difficult because
> everything that is removed here is not returned in the further patches.
> The new driver is based on the older ones, but I wrote it from scratch
> and it's not only looks different, but also works a bit different as you
> may see.
> 
> Could you please clarify what exactly makes it hard to review? The diff
> looks pretty clean to me, while squashing everything into existing
> driver should be quite a mess.

Ideally a patch should standalone and can be reviewed by itself.
However, to review this, we need to review patches 1, 2 and 3 at the
same time. So IMO it is not that convenient from a reviewers
perspective. Furthermore, patches 1 and 3 are large and so easy to miss
something.

Is there really no way to have a patch to combined the existing drivers,
then a patch to convert them into the newer rewritten version you have
implemented, then move the driver?

Jon

-- 
nvpublic

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
  2019-07-12  9:39         ` Jon Hunter
@ 2019-07-12 16:23           ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-12 16:23 UTC (permalink / raw)
  To: Jon Hunter, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

12.07.2019 12:39, Jon Hunter пишет:
> 
> On 11/07/2019 18:03, Dmitry Osipenko wrote:
>> 11.07.2019 12:26, Jon Hunter пишет:
>>>
>>> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>>>> Remove the old drivers to replace them cleanly with a new one later on.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>>  arch/arm/mach-tegra/Makefile           |  13 --
>>>>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>>>>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>>>>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>>>>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>>>>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>>>>  arch/arm/mach-tegra/irq.c              |  18 ---
>>>>  arch/arm/mach-tegra/irq.h              |  11 --
>>>>  arch/arm/mach-tegra/pm.c               |   7 -
>>>>  arch/arm/mach-tegra/pm.h               |   1 -
>>>>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>>>>  arch/arm/mach-tegra/reset.h            |   9 +-
>>>>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>>>>  arch/arm/mach-tegra/sleep.h            |  12 --
>>>>  arch/arm/mach-tegra/tegra.c            |   3 -
>>>>  drivers/soc/tegra/Kconfig              |   1 -
>>>>  include/soc/tegra/cpuidle.h            |   4 -
>>>>  17 files changed, 5 insertions(+), 779 deletions(-)
>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>>>>  delete mode 100644 arch/arm/mach-tegra/irq.h
>>>
>>> By removing all the above, it is really hard to review the diff. Is
>>> there any way you could first consolidate the cpuidle drivers into say
>>> the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
>>> drivers/cpuidle?
>>
>> I'm afraid that it will make reviewing even more difficult because
>> everything that is removed here is not returned in the further patches.
>> The new driver is based on the older ones, but I wrote it from scratch
>> and it's not only looks different, but also works a bit different as you
>> may see.
>>
>> Could you please clarify what exactly makes it hard to review? The diff
>> looks pretty clean to me, while squashing everything into existing
>> driver should be quite a mess.
> 
> Ideally a patch should standalone and can be reviewed by itself.
> However, to review this, we need to review patches 1, 2 and 3 at the
> same time. So IMO it is not that convenient from a reviewers
> perspective. Furthermore, patches 1 and 3 are large and so easy to miss
> something.
> 
> Is there really no way to have a patch to combined the existing drivers,
> then a patch to convert them into the newer rewritten version you have
> implemented, then move the driver?

Probably I spent a bit too much time with that code, so now yours
suggestion looks to me like an unnecessary step. But I will try and see
how it goes, at least it should be possible to break down the patch 1 a
bit more, hopefully it will help to better understand what's going on in
the further patches if you're not familiar or don't remember how it all
works.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
@ 2019-07-12 16:23           ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-12 16:23 UTC (permalink / raw)
  To: Jon Hunter, Thierry Reding, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

12.07.2019 12:39, Jon Hunter пишет:
> 
> On 11/07/2019 18:03, Dmitry Osipenko wrote:
>> 11.07.2019 12:26, Jon Hunter пишет:
>>>
>>> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>>>> Remove the old drivers to replace them cleanly with a new one later on.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>>  arch/arm/mach-tegra/Makefile           |  13 --
>>>>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>>>>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>>>>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>>>>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>>>>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>>>>  arch/arm/mach-tegra/irq.c              |  18 ---
>>>>  arch/arm/mach-tegra/irq.h              |  11 --
>>>>  arch/arm/mach-tegra/pm.c               |   7 -
>>>>  arch/arm/mach-tegra/pm.h               |   1 -
>>>>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>>>>  arch/arm/mach-tegra/reset.h            |   9 +-
>>>>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>>>>  arch/arm/mach-tegra/sleep.h            |  12 --
>>>>  arch/arm/mach-tegra/tegra.c            |   3 -
>>>>  drivers/soc/tegra/Kconfig              |   1 -
>>>>  include/soc/tegra/cpuidle.h            |   4 -
>>>>  17 files changed, 5 insertions(+), 779 deletions(-)
>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>>>>  delete mode 100644 arch/arm/mach-tegra/irq.h
>>>
>>> By removing all the above, it is really hard to review the diff. Is
>>> there any way you could first consolidate the cpuidle drivers into say
>>> the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
>>> drivers/cpuidle?
>>
>> I'm afraid that it will make reviewing even more difficult because
>> everything that is removed here is not returned in the further patches.
>> The new driver is based on the older ones, but I wrote it from scratch
>> and it's not only looks different, but also works a bit different as you
>> may see.
>>
>> Could you please clarify what exactly makes it hard to review? The diff
>> looks pretty clean to me, while squashing everything into existing
>> driver should be quite a mess.
> 
> Ideally a patch should standalone and can be reviewed by itself.
> However, to review this, we need to review patches 1, 2 and 3 at the
> same time. So IMO it is not that convenient from a reviewers
> perspective. Furthermore, patches 1 and 3 are large and so easy to miss
> something.
> 
> Is there really no way to have a patch to combined the existing drivers,
> then a patch to convert them into the newer rewritten version you have
> implemented, then move the driver?

Probably I spent a bit too much time with that code, so now yours
suggestion looks to me like an unnecessary step. But I will try and see
how it goes, at least it should be possible to break down the patch 1 a
bit more, hopefully it will help to better understand what's going on in
the further patches if you're not familiar or don't remember how it all
works.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 3/6] cpuidle: Add unified driver for NVIDIA Tegra SoCs
  2019-07-11 18:35     ` Dmitry Osipenko
@ 2019-07-12 16:41       ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-12 16:41 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-pm, linux-tegra, linux-arm-kernel, linux-kernel

11.07.2019 21:35, Dmitry Osipenko пишет:
> 11.07.2019 6:13, Dmitry Osipenko пишет:
>> The new driver is based on the old CPU Idle drivers that are removed now
>> from arm/arch/mach-tegra/ directory. Those removed drivers were reworked
>> and squashed into a single unified driver that covers multiple hardware
>> generations, starting from Tegra20 and ending with Tegra124.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  arch/arm/mach-tegra/tegra.c     |   4 +
>>  drivers/cpuidle/Kconfig.arm     |   8 +
>>  drivers/cpuidle/Makefile        |   1 +
>>  drivers/cpuidle/cpuidle-tegra.c | 304 ++++++++++++++++++++++++++++++++
>>  include/soc/tegra/cpuidle.h     |   4 +
>>  5 files changed, 321 insertions(+)
>>  create mode 100644 drivers/cpuidle/cpuidle-tegra.c
>>
>> diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
>> index d9237769a37c..f1ce2857a251 100644
>> --- a/arch/arm/mach-tegra/tegra.c
>> +++ b/arch/arm/mach-tegra/tegra.c
>> @@ -36,6 +36,7 @@
>>  #include <asm/mach/arch.h>
>>  #include <asm/mach/time.h>
>>  #include <asm/mach-types.h>
>> +#include <asm/psci.h>
>>  #include <asm/setup.h>
>>  
>>  #include "board.h"
>> @@ -92,6 +93,9 @@ static void __init tegra_dt_init_late(void)
>>  	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
>>  	    of_machine_is_compatible("nvidia,tegra20"))
>>  		platform_device_register_simple("tegra20-cpufreq", -1, NULL, 0);
>> +
>> +	if (IS_ENABLED(CONFIG_ARM_TEGRA_CPUIDLE) && !psci_smp_available())
>> +		platform_device_register_simple("tegra-cpuidle", -1, NULL, 0);
>>  }
>>  
>>  static const char * const tegra_dt_board_compat[] = {
>> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
>> index 48cb3d4bb7d1..d90861361f1d 100644
>> --- a/drivers/cpuidle/Kconfig.arm
>> +++ b/drivers/cpuidle/Kconfig.arm
>> @@ -76,3 +76,11 @@ config ARM_MVEBU_V7_CPUIDLE
>>  	depends on ARCH_MVEBU && !ARM64
>>  	help
>>  	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
>> +
>> +config ARM_TEGRA_CPUIDLE
>> +	bool "CPU Idle Driver for NVIDIA Tegra SoCs"
>> +	depends on ARCH_TEGRA && !ARM64
>> +	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
>> +	select ARM_CPU_SUSPEND
>> +	help
>> +	  Select this to enable cpuidle for NVIDIA Tegra20/30/114/124 SoCs.
>> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
>> index 9d7176cee3d3..470d17fa8746 100644
>> --- a/drivers/cpuidle/Makefile
>> +++ b/drivers/cpuidle/Makefile
>> @@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
>>  obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
>>  obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
>>  obj-$(CONFIG_ARM_CPUIDLE)		+= cpuidle-arm.o
>> +obj-$(CONFIG_ARM_TEGRA_CPUIDLE)		+= cpuidle-tegra.o
>>  
>>  ###############################################################################
>>  # MIPS drivers
>> diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c
>> new file mode 100644
>> index 000000000000..54974cd2255f
>> --- /dev/null
>> +++ b/drivers/cpuidle/cpuidle-tegra.c
>> @@ -0,0 +1,304 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * CPU idle driver for Tegra CPUs
>> + *
>> + * Copyright (c) 2010-2013, 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>
>> + *
>> + * Tegra20/124 driver unification by Dmitry Osipenko <digetx@gmail.com>
>> + */
>> +
>> +#include <linux/cpuidle.h>
>> +#include <linux/cpumask.h>
>> +#include <linux/cpu_pm.h>
>> +#include <linux/errno.h>
>> +#include <linux/ktime.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/types.h>
>> +
>> +#include <linux/clk/tegra.h>
>> +#include <linux/firmware/trusted_foundations.h>
>> +
>> +#include <soc/tegra/cpuidle.h>
>> +#include <soc/tegra/flowctrl.h>
>> +#include <soc/tegra/fuse.h>
>> +#include <soc/tegra/pm.h>
>> +
>> +#include <asm/cpuidle.h>
>> +#include <asm/firmware.h>
>> +#include <asm/smp_plat.h>
>> +#include <asm/suspend.h>
>> +
>> +#define TEGRA_C1		0
>> +#define TEGRA_C7		1
>> +#define TEGRA_CC6		2
>> +
>> +static atomic_t tegra_idle_barrier;
>> +
>> +static inline bool tegra_cpuidle_using_firmware(void)
>> +{
>> +	return firmware_ops->prepare_idle && firmware_ops->do_idle;
>> +}
>> +
>> +static int tegra_shutdown_secondary_cpu(unsigned long cpu)
>> +{
>> +	tegra_cpu_die(cpu);
>> +
>> +	return -EINVAL;
>> +}
>> +
>> +static int tegra_await_secondary_cpus_shutdown(void)
>> +{
>> +	ktime_t timeout = ktime_add_ms(ktime_get(), 1);
>> +
>> +	/*
>> +	 * The boot CPU shall await for the secondaries shutdown in order
>> +	 * to power-off CPU's cluster safely.
>> +	 */
>> +	do {
>> +		if (tegra_cpu_rail_off_ready())
>> +			return 0;
>> +
>> +	} while (ktime_compare(ktime_get(), timeout) < 0);
>> +
>> +	return -ETIMEDOUT;
>> +}
>> +
>> +static void tegra_wake_up_secondary_cpus(void)
>> +{
>> +	unsigned int cpu, lcpu;
>> +
>> +	for_each_cpu(lcpu, cpu_online_mask) {
>> +		cpu = cpu_logical_map(lcpu);
>> +
>> +		if (cpu > 0) {
>> +			tegra_enable_cpu_clock(cpu);
>> +			tegra_cpu_out_of_reset(cpu);
>> +			flowctrl_write_cpu_halt(cpu, 0);
>> +		}
>> +	}
>> +}
>> +
>> +static int tegra_cpuidle_cc6_enter(void)
>> +{
>> +	int err;
>> +
>> +	err = tegra_await_secondary_cpus_shutdown();
>> +	if (err)
>> +		return err;
>> +
>> +	err = tegra_idle_lp2_last();
>> +
>> +	tegra_wake_up_secondary_cpus();
>> +
>> +	return err;
>> +}
>> +
>> +static int tegra_cpuidle_c7_enter(void)
>> +{
>> +	int err;
>> +
>> +	if (tegra_cpuidle_using_firmware()) {
>> +		err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
>> +		if (err)
>> +			return err;
>> +
>> +		return call_firmware_op(do_idle, 0);
>> +	}
>> +
>> +	return cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
>> +}
>> +
>> +static int tegra_cpuidle_enter(struct cpuidle_device *dev,
>> +			       int index, unsigned int cpu)
>> +{
>> +	int err;
>> +
>> +	local_fiq_disable();
>> +	tegra_set_cpu_in_lp2();
>> +	cpu_pm_enter();
>> +
>> +	switch (index) {
>> +	case TEGRA_C7:
>> +		err = tegra_cpuidle_c7_enter();
>> +		break;
>> +	case TEGRA_CC6:
>> +		cpuidle_coupled_parallel_barrier(dev, &tegra_idle_barrier);
> 
> I realized that this is not very correct. We still need to do a proper
> barrier with SGI checking in order to bail out if other CPU sent IPI
> during of the awaiting for a coupled barrier to avoid the overhead of
> unnecessary power-gating. Will correct that in the next revision.

UPDATE: Actually, turned out it's even a necessity to handle the SGI
because GIC's driver doesn't save and replay SGI across CPU cluster PM.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 3/6] cpuidle: Add unified driver for NVIDIA Tegra SoCs
@ 2019-07-12 16:41       ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-12 16:41 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter De Schrijver,
	Rafael J. Wysocki, Daniel Lezcano
  Cc: linux-tegra, linux-kernel, linux-arm-kernel, linux-pm

11.07.2019 21:35, Dmitry Osipenko пишет:
> 11.07.2019 6:13, Dmitry Osipenko пишет:
>> The new driver is based on the old CPU Idle drivers that are removed now
>> from arm/arch/mach-tegra/ directory. Those removed drivers were reworked
>> and squashed into a single unified driver that covers multiple hardware
>> generations, starting from Tegra20 and ending with Tegra124.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  arch/arm/mach-tegra/tegra.c     |   4 +
>>  drivers/cpuidle/Kconfig.arm     |   8 +
>>  drivers/cpuidle/Makefile        |   1 +
>>  drivers/cpuidle/cpuidle-tegra.c | 304 ++++++++++++++++++++++++++++++++
>>  include/soc/tegra/cpuidle.h     |   4 +
>>  5 files changed, 321 insertions(+)
>>  create mode 100644 drivers/cpuidle/cpuidle-tegra.c
>>
>> diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
>> index d9237769a37c..f1ce2857a251 100644
>> --- a/arch/arm/mach-tegra/tegra.c
>> +++ b/arch/arm/mach-tegra/tegra.c
>> @@ -36,6 +36,7 @@
>>  #include <asm/mach/arch.h>
>>  #include <asm/mach/time.h>
>>  #include <asm/mach-types.h>
>> +#include <asm/psci.h>
>>  #include <asm/setup.h>
>>  
>>  #include "board.h"
>> @@ -92,6 +93,9 @@ static void __init tegra_dt_init_late(void)
>>  	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
>>  	    of_machine_is_compatible("nvidia,tegra20"))
>>  		platform_device_register_simple("tegra20-cpufreq", -1, NULL, 0);
>> +
>> +	if (IS_ENABLED(CONFIG_ARM_TEGRA_CPUIDLE) && !psci_smp_available())
>> +		platform_device_register_simple("tegra-cpuidle", -1, NULL, 0);
>>  }
>>  
>>  static const char * const tegra_dt_board_compat[] = {
>> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
>> index 48cb3d4bb7d1..d90861361f1d 100644
>> --- a/drivers/cpuidle/Kconfig.arm
>> +++ b/drivers/cpuidle/Kconfig.arm
>> @@ -76,3 +76,11 @@ config ARM_MVEBU_V7_CPUIDLE
>>  	depends on ARCH_MVEBU && !ARM64
>>  	help
>>  	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
>> +
>> +config ARM_TEGRA_CPUIDLE
>> +	bool "CPU Idle Driver for NVIDIA Tegra SoCs"
>> +	depends on ARCH_TEGRA && !ARM64
>> +	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
>> +	select ARM_CPU_SUSPEND
>> +	help
>> +	  Select this to enable cpuidle for NVIDIA Tegra20/30/114/124 SoCs.
>> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
>> index 9d7176cee3d3..470d17fa8746 100644
>> --- a/drivers/cpuidle/Makefile
>> +++ b/drivers/cpuidle/Makefile
>> @@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
>>  obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
>>  obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
>>  obj-$(CONFIG_ARM_CPUIDLE)		+= cpuidle-arm.o
>> +obj-$(CONFIG_ARM_TEGRA_CPUIDLE)		+= cpuidle-tegra.o
>>  
>>  ###############################################################################
>>  # MIPS drivers
>> diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c
>> new file mode 100644
>> index 000000000000..54974cd2255f
>> --- /dev/null
>> +++ b/drivers/cpuidle/cpuidle-tegra.c
>> @@ -0,0 +1,304 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * CPU idle driver for Tegra CPUs
>> + *
>> + * Copyright (c) 2010-2013, 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>
>> + *
>> + * Tegra20/124 driver unification by Dmitry Osipenko <digetx@gmail.com>
>> + */
>> +
>> +#include <linux/cpuidle.h>
>> +#include <linux/cpumask.h>
>> +#include <linux/cpu_pm.h>
>> +#include <linux/errno.h>
>> +#include <linux/ktime.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/types.h>
>> +
>> +#include <linux/clk/tegra.h>
>> +#include <linux/firmware/trusted_foundations.h>
>> +
>> +#include <soc/tegra/cpuidle.h>
>> +#include <soc/tegra/flowctrl.h>
>> +#include <soc/tegra/fuse.h>
>> +#include <soc/tegra/pm.h>
>> +
>> +#include <asm/cpuidle.h>
>> +#include <asm/firmware.h>
>> +#include <asm/smp_plat.h>
>> +#include <asm/suspend.h>
>> +
>> +#define TEGRA_C1		0
>> +#define TEGRA_C7		1
>> +#define TEGRA_CC6		2
>> +
>> +static atomic_t tegra_idle_barrier;
>> +
>> +static inline bool tegra_cpuidle_using_firmware(void)
>> +{
>> +	return firmware_ops->prepare_idle && firmware_ops->do_idle;
>> +}
>> +
>> +static int tegra_shutdown_secondary_cpu(unsigned long cpu)
>> +{
>> +	tegra_cpu_die(cpu);
>> +
>> +	return -EINVAL;
>> +}
>> +
>> +static int tegra_await_secondary_cpus_shutdown(void)
>> +{
>> +	ktime_t timeout = ktime_add_ms(ktime_get(), 1);
>> +
>> +	/*
>> +	 * The boot CPU shall await for the secondaries shutdown in order
>> +	 * to power-off CPU's cluster safely.
>> +	 */
>> +	do {
>> +		if (tegra_cpu_rail_off_ready())
>> +			return 0;
>> +
>> +	} while (ktime_compare(ktime_get(), timeout) < 0);
>> +
>> +	return -ETIMEDOUT;
>> +}
>> +
>> +static void tegra_wake_up_secondary_cpus(void)
>> +{
>> +	unsigned int cpu, lcpu;
>> +
>> +	for_each_cpu(lcpu, cpu_online_mask) {
>> +		cpu = cpu_logical_map(lcpu);
>> +
>> +		if (cpu > 0) {
>> +			tegra_enable_cpu_clock(cpu);
>> +			tegra_cpu_out_of_reset(cpu);
>> +			flowctrl_write_cpu_halt(cpu, 0);
>> +		}
>> +	}
>> +}
>> +
>> +static int tegra_cpuidle_cc6_enter(void)
>> +{
>> +	int err;
>> +
>> +	err = tegra_await_secondary_cpus_shutdown();
>> +	if (err)
>> +		return err;
>> +
>> +	err = tegra_idle_lp2_last();
>> +
>> +	tegra_wake_up_secondary_cpus();
>> +
>> +	return err;
>> +}
>> +
>> +static int tegra_cpuidle_c7_enter(void)
>> +{
>> +	int err;
>> +
>> +	if (tegra_cpuidle_using_firmware()) {
>> +		err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
>> +		if (err)
>> +			return err;
>> +
>> +		return call_firmware_op(do_idle, 0);
>> +	}
>> +
>> +	return cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
>> +}
>> +
>> +static int tegra_cpuidle_enter(struct cpuidle_device *dev,
>> +			       int index, unsigned int cpu)
>> +{
>> +	int err;
>> +
>> +	local_fiq_disable();
>> +	tegra_set_cpu_in_lp2();
>> +	cpu_pm_enter();
>> +
>> +	switch (index) {
>> +	case TEGRA_C7:
>> +		err = tegra_cpuidle_c7_enter();
>> +		break;
>> +	case TEGRA_CC6:
>> +		cpuidle_coupled_parallel_barrier(dev, &tegra_idle_barrier);
> 
> I realized that this is not very correct. We still need to do a proper
> barrier with SGI checking in order to bail out if other CPU sent IPI
> during of the awaiting for a coupled barrier to avoid the overhead of
> unnecessary power-gating. Will correct that in the next revision.

UPDATE: Actually, turned out it's even a necessity to handle the SGI
because GIC's driver doesn't save and replay SGI across CPU cluster PM.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
  2019-07-12 16:23           ` Dmitry Osipenko
@ 2019-07-14 22:19             ` Dmitry Osipenko
  -1 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-14 22:19 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-pm, Peter De Schrijver, Daniel Lezcano, Rafael J. Wysocki,
	linux-kernel, Thierry Reding, linux-tegra, linux-arm-kernel

12.07.2019 19:23, Dmitry Osipenko пишет:
> 12.07.2019 12:39, Jon Hunter пишет:
>>
>> On 11/07/2019 18:03, Dmitry Osipenko wrote:
>>> 11.07.2019 12:26, Jon Hunter пишет:
>>>>
>>>> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>>>>> Remove the old drivers to replace them cleanly with a new one later on.
>>>>>
>>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>>> ---
>>>>>  arch/arm/mach-tegra/Makefile           |  13 --
>>>>>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>>>>>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>>>>>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>>>>>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>>>>>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>>>>>  arch/arm/mach-tegra/irq.c              |  18 ---
>>>>>  arch/arm/mach-tegra/irq.h              |  11 --
>>>>>  arch/arm/mach-tegra/pm.c               |   7 -
>>>>>  arch/arm/mach-tegra/pm.h               |   1 -
>>>>>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>>>>>  arch/arm/mach-tegra/reset.h            |   9 +-
>>>>>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>>>>>  arch/arm/mach-tegra/sleep.h            |  12 --
>>>>>  arch/arm/mach-tegra/tegra.c            |   3 -
>>>>>  drivers/soc/tegra/Kconfig              |   1 -
>>>>>  include/soc/tegra/cpuidle.h            |   4 -
>>>>>  17 files changed, 5 insertions(+), 779 deletions(-)
>>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>>>>>  delete mode 100644 arch/arm/mach-tegra/irq.h
>>>>
>>>> By removing all the above, it is really hard to review the diff. Is
>>>> there any way you could first consolidate the cpuidle drivers into say
>>>> the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
>>>> drivers/cpuidle?
>>>
>>> I'm afraid that it will make reviewing even more difficult because
>>> everything that is removed here is not returned in the further patches.
>>> The new driver is based on the older ones, but I wrote it from scratch
>>> and it's not only looks different, but also works a bit different as you
>>> may see.
>>>
>>> Could you please clarify what exactly makes it hard to review? The diff
>>> looks pretty clean to me, while squashing everything into existing
>>> driver should be quite a mess.
>>
>> Ideally a patch should standalone and can be reviewed by itself.
>> However, to review this, we need to review patches 1, 2 and 3 at the
>> same time. So IMO it is not that convenient from a reviewers
>> perspective. Furthermore, patches 1 and 3 are large and so easy to miss
>> something.
>>
>> Is there really no way to have a patch to combined the existing drivers,
>> then a patch to convert them into the newer rewritten version you have
>> implemented, then move the driver?
> 
> Probably I spent a bit too much time with that code, so now yours
> suggestion looks to me like an unnecessary step. But I will try and see
> how it goes, at least it should be possible to break down the patch 1 a
> bit more, hopefully it will help to better understand what's going on in
> the further patches if you're not familiar or don't remember how it all
> works.

I tried (in several attempts) and couldn't find a way how to
meaningfully squash the old drivers. It's a lot of unnecessary churning
that won't help with reviewing of the code at all because new driver is
structured differently and beating of old drivers until they resemble
the new one just not worth it. I'll write a bit more detailed commit
message, emphasizing the details, hope it will be helpful. The old
drivers are ~200 LOC each and the new one will be ~300 LOC + 50 lines of
comments, I don't think that it's really very hard to review as it it
may initially looked like to you, Jon.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers
@ 2019-07-14 22:19             ` Dmitry Osipenko
  0 siblings, 0 replies; 35+ messages in thread
From: Dmitry Osipenko @ 2019-07-14 22:19 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Thierry Reding, Peter De Schrijver, Rafael J. Wysocki,
	Daniel Lezcano, linux-pm, linux-tegra, linux-arm-kernel,
	linux-kernel

12.07.2019 19:23, Dmitry Osipenko пишет:
> 12.07.2019 12:39, Jon Hunter пишет:
>>
>> On 11/07/2019 18:03, Dmitry Osipenko wrote:
>>> 11.07.2019 12:26, Jon Hunter пишет:
>>>>
>>>> On 11/07/2019 04:13, Dmitry Osipenko wrote:
>>>>> Remove the old drivers to replace them cleanly with a new one later on.
>>>>>
>>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>>> ---
>>>>>  arch/arm/mach-tegra/Makefile           |  13 --
>>>>>  arch/arm/mach-tegra/cpuidle-tegra114.c |  89 -----------
>>>>>  arch/arm/mach-tegra/cpuidle-tegra20.c  | 212 -------------------------
>>>>>  arch/arm/mach-tegra/cpuidle-tegra30.c  | 132 ---------------
>>>>>  arch/arm/mach-tegra/cpuidle.c          |  50 ------
>>>>>  arch/arm/mach-tegra/cpuidle.h          |  21 ---
>>>>>  arch/arm/mach-tegra/irq.c              |  18 ---
>>>>>  arch/arm/mach-tegra/irq.h              |  11 --
>>>>>  arch/arm/mach-tegra/pm.c               |   7 -
>>>>>  arch/arm/mach-tegra/pm.h               |   1 -
>>>>>  arch/arm/mach-tegra/reset-handler.S    |  11 --
>>>>>  arch/arm/mach-tegra/reset.h            |   9 +-
>>>>>  arch/arm/mach-tegra/sleep-tegra20.S    | 190 +---------------------
>>>>>  arch/arm/mach-tegra/sleep.h            |  12 --
>>>>>  arch/arm/mach-tegra/tegra.c            |   3 -
>>>>>  drivers/soc/tegra/Kconfig              |   1 -
>>>>>  include/soc/tegra/cpuidle.h            |   4 -
>>>>>  17 files changed, 5 insertions(+), 779 deletions(-)
>>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c
>>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c
>>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c
>>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.c
>>>>>  delete mode 100644 arch/arm/mach-tegra/cpuidle.h
>>>>>  delete mode 100644 arch/arm/mach-tegra/irq.h
>>>>
>>>> By removing all the above, it is really hard to review the diff. Is
>>>> there any way you could first consolidate the cpuidle drivers into say
>>>> the existing arch/arm/mach-tegra/cpuidle-tegra20.c and then move to
>>>> drivers/cpuidle?
>>>
>>> I'm afraid that it will make reviewing even more difficult because
>>> everything that is removed here is not returned in the further patches.
>>> The new driver is based on the older ones, but I wrote it from scratch
>>> and it's not only looks different, but also works a bit different as you
>>> may see.
>>>
>>> Could you please clarify what exactly makes it hard to review? The diff
>>> looks pretty clean to me, while squashing everything into existing
>>> driver should be quite a mess.
>>
>> Ideally a patch should standalone and can be reviewed by itself.
>> However, to review this, we need to review patches 1, 2 and 3 at the
>> same time. So IMO it is not that convenient from a reviewers
>> perspective. Furthermore, patches 1 and 3 are large and so easy to miss
>> something.
>>
>> Is there really no way to have a patch to combined the existing drivers,
>> then a patch to convert them into the newer rewritten version you have
>> implemented, then move the driver?
> 
> Probably I spent a bit too much time with that code, so now yours
> suggestion looks to me like an unnecessary step. But I will try and see
> how it goes, at least it should be possible to break down the patch 1 a
> bit more, hopefully it will help to better understand what's going on in
> the further patches if you're not familiar or don't remember how it all
> works.

I tried (in several attempts) and couldn't find a way how to
meaningfully squash the old drivers. It's a lot of unnecessary churning
that won't help with reviewing of the code at all because new driver is
structured differently and beating of old drivers until they resemble
the new one just not worth it. I'll write a bit more detailed commit
message, emphasizing the details, hope it will be helpful. The old
drivers are ~200 LOC each and the new one will be ~300 LOC + 50 lines of
comments, I don't think that it's really very hard to review as it it
may initially looked like to you, Jon.

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2019-07-14 22:19 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-11  3:13 [PATCH v2 0/6] Consolidate and improve NVIDIA Tegra CPUIDLE driver(s) Dmitry Osipenko
2019-07-11  3:13 ` Dmitry Osipenko
2019-07-11  3:13 ` [PATCH v2 1/6] ARM: tegra: Remove cpuidle drivers Dmitry Osipenko
2019-07-11  3:13   ` Dmitry Osipenko
2019-07-11  9:26   ` Jon Hunter
2019-07-11  9:26     ` Jon Hunter
2019-07-11  9:26     ` Jon Hunter
2019-07-11 17:03     ` Dmitry Osipenko
2019-07-11 17:03       ` Dmitry Osipenko
2019-07-12  9:39       ` Jon Hunter
2019-07-12  9:39         ` Jon Hunter
2019-07-12  9:39         ` Jon Hunter
2019-07-12 16:23         ` Dmitry Osipenko
2019-07-12 16:23           ` Dmitry Osipenko
2019-07-14 22:19           ` Dmitry Osipenko
2019-07-14 22:19             ` Dmitry Osipenko
2019-07-11  3:13 ` [PATCH v2 2/6] ARM: tegra: Expose functions required for cpuidle driver Dmitry Osipenko
2019-07-11  3:13   ` Dmitry Osipenko
2019-07-11 12:42   ` Jon Hunter
2019-07-11 12:42     ` Jon Hunter
2019-07-11 12:42     ` Jon Hunter
2019-07-11 17:25     ` Dmitry Osipenko
2019-07-11 17:25       ` Dmitry Osipenko
2019-07-11  3:13 ` [PATCH v2 3/6] cpuidle: Add unified driver for NVIDIA Tegra SoCs Dmitry Osipenko
2019-07-11  3:13   ` Dmitry Osipenko
2019-07-11 18:35   ` Dmitry Osipenko
2019-07-11 18:35     ` Dmitry Osipenko
2019-07-12 16:41     ` Dmitry Osipenko
2019-07-12 16:41       ` Dmitry Osipenko
2019-07-11  3:13 ` [PATCH v2 4/6] cpuidle: tegra: Support CPU cluster power-down on Tegra30 Dmitry Osipenko
2019-07-11  3:13   ` Dmitry Osipenko
2019-07-11  3:13 ` [PATCH v2 5/6] ARM: multi_v7_defconfig: Enable Tegra cpuidle driver Dmitry Osipenko
2019-07-11  3:13   ` Dmitry Osipenko
2019-07-11  3:13 ` [PATCH v2 6/6] ARM: tegra: Enable Tegra cpuidle driver in tegra_defconfig Dmitry Osipenko
2019-07-11  3:13   ` Dmitry Osipenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.