Browse Source

Merge tag 'tegra-for-4.2-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/soc

Merge "ARM: tegra: Core SoC changes for v4.2-rc1" from Thierry Reding:

A couple of changes to the core SoC support code. Perhaps the most
important part is a fix for a regression in LP1 suspend/resume code that
was introduced a while back.

* tag 'tegra-for-4.2-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  soc/tegra: pmc: move to using a restart handler
  ARM: tegra20: Store CPU "resettable" status in IRAM
  soc/tegra: Watch wait_for_completion_timeout() return type
Arnd Bergmann 10 years ago
parent
commit
2516a932ef

+ 2 - 3
arch/arm/mach-tegra/cpuidle-tegra20.c

@@ -34,6 +34,7 @@
 #include "iomap.h"
 #include "irq.h"
 #include "pm.h"
+#include "reset.h"
 #include "sleep.h"
 
 #ifdef CONFIG_PM_SLEEP
@@ -70,15 +71,13 @@ static struct cpuidle_driver tegra_idle_driver = {
 
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_SMP
-static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
-
 static int tegra20_reset_sleeping_cpu_1(void)
 {
 	int ret = 0;
 
 	tegra_pen_lock();
 
-	if (readl(pmc + PMC_SCRATCH41) == CPU_RESETTABLE)
+	if (readb(tegra20_cpu1_resettable_status) == CPU_RESETTABLE)
 		tegra20_cpu_shutdown(1);
 	else
 		ret = -EINVAL;

+ 7 - 3
arch/arm/mach-tegra/reset-handler.S

@@ -169,10 +169,10 @@ after_errata:
 	cmp	r6, #TEGRA20
 	bne	1f
 	/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
-	mov32	r5, TEGRA_PMC_BASE
-	mov	r0, #0
+	mov32	r5, TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET
+	mov	r0, #CPU_NOT_RESETTABLE
 	cmp	r10, #0
-	strne	r0, [r5, #PMC_SCRATCH41]
+	strneb	r0, [r5, #__tegra20_cpu1_resettable_status_offset]
 1:
 #endif
 
@@ -281,6 +281,10 @@ __tegra_cpu_reset_handler_data:
 	.rept	TEGRA_RESET_DATA_SIZE
 	.long	0
 	.endr
+	.globl	__tegra20_cpu1_resettable_status_offset
+	.equ	__tegra20_cpu1_resettable_status_offset, \
+					. - __tegra_cpu_reset_handler_start
+	.byte	0
 	.align L1_CACHE_SHIFT
 
 ENTRY(__tegra_cpu_reset_handler_end)

+ 4 - 0
arch/arm/mach-tegra/reset.h

@@ -35,6 +35,7 @@ extern unsigned long __tegra_cpu_reset_handler_data[TEGRA_RESET_DATA_SIZE];
 
 void __tegra_cpu_reset_handler_start(void);
 void __tegra_cpu_reset_handler(void);
+void __tegra20_cpu1_resettable_status_offset(void);
 void __tegra_cpu_reset_handler_end(void);
 void tegra_secondary_startup(void);
 
@@ -47,6 +48,9 @@ void tegra_secondary_startup(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)__tegra20_cpu1_resettable_status_offset))
 #endif
 
 #define tegra_cpu_reset_handler_offset \

+ 21 - 16
arch/arm/mach-tegra/sleep-tegra20.S

@@ -97,9 +97,10 @@ ENDPROC(tegra20_hotplug_shutdown)
 ENTRY(tegra20_cpu_shutdown)
 	cmp	r0, #0
 	reteq	lr			@ must not be called for CPU 0
-	mov32	r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
+	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
+	ldr	r2, =__tegra20_cpu1_resettable_status_offset
 	mov	r12, #CPU_RESETTABLE
-	str	r12, [r1]
+	strb	r12, [r1, r2]
 
 	cpu_to_halt_reg r1, r0
 	ldr	r3, =TEGRA_FLOW_CTRL_VIRT
@@ -182,38 +183,41 @@ ENDPROC(tegra_pen_unlock)
 /*
  * tegra20_cpu_clear_resettable(void)
  *
- * Called to clear the "resettable soon" flag in PMC_SCRATCH41 when
+ * 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_PMC_VIRT + PMC_SCRATCH41
+	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
+	ldr	r2, =__tegra20_cpu1_resettable_status_offset
 	mov	r12, #CPU_NOT_RESETTABLE
-	str	r12, [r1]
+	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 PMC_SCRATCH41 when
+ * 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_PMC_VIRT + PMC_SCRATCH41
+	mov32	r1, TEGRA_IRAM_RESET_BASE_VIRT
+	ldr	r2, =__tegra20_cpu1_resettable_status_offset
 	mov	r12, #CPU_RESETTABLE_SOON
-	str	r12, [r1]
+	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 PMC_SCRATCH41 has been
+ * 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_PMC_VIRT + PMC_SCRATCH41
-	ldr	r12, [r1]
+	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
@@ -256,9 +260,10 @@ ENTRY(tegra20_sleep_cpu_secondary_finish)
 	mov	r0, #TEGRA_FLUSH_CACHE_LOUIS
 	bl	tegra_disable_clean_inv_dcache
 
-	mov32	r0, TEGRA_PMC_VIRT + PMC_SCRATCH41
+	mov32	r0, TEGRA_IRAM_RESET_BASE_VIRT
+	ldr	r4, =__tegra20_cpu1_resettable_status_offset
 	mov	r3, #CPU_RESETTABLE
-	str	r3, [r0]
+	strb	r3, [r0, r4]
 
 	bl	tegra_cpu_do_idle
 
@@ -274,10 +279,10 @@ ENTRY(tegra20_sleep_cpu_secondary_finish)
 
 	bl	tegra_pen_lock
 
-	mov32	r3, TEGRA_PMC_VIRT
-	add	r0, r3, #PMC_SCRATCH41
+	mov32	r0, TEGRA_IRAM_RESET_BASE_VIRT
+	ldr	r4, =__tegra20_cpu1_resettable_status_offset
 	mov	r3, #CPU_NOT_RESETTABLE
-	str	r3, [r0]
+	strb	r3, [r0, r4]
 
 	bl	tegra_pen_unlock
 

+ 4 - 0
arch/arm/mach-tegra/sleep.h

@@ -18,6 +18,7 @@
 #define __MACH_TEGRA_SLEEP_H
 
 #include "iomap.h"
+#include "irammap.h"
 
 #define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \
 					+ IO_CPU_VIRT)
@@ -29,6 +30,9 @@
 					+ IO_APB_VIRT)
 #define TEGRA_PMC_VIRT	(TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
 
+#define TEGRA_IRAM_RESET_BASE_VIRT (IO_IRAM_VIRT + \
+				TEGRA_IRAM_RESET_HANDLER_OFFSET)
+
 /* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */
 #define PMC_SCRATCH37	0x130
 #define PMC_SCRATCH38	0x134

+ 0 - 1
arch/arm/mach-tegra/tegra.c

@@ -163,6 +163,5 @@ DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
 	.init_irq	= tegra_dt_init_irq,
 	.init_machine	= tegra_dt_init,
 	.init_late	= tegra_dt_init_late,
-	.restart	= tegra_pmc_restart,
 	.dt_compat	= tegra_dt_board_compat,
 MACHINE_END

+ 4 - 2
drivers/soc/tegra/fuse/fuse-tegra20.c

@@ -59,6 +59,7 @@ static u32 tegra20_fuse_readl(const unsigned int offset)
 	int ret;
 	u32 val = 0;
 	struct dma_async_tx_descriptor *dma_desc;
+	unsigned long time_left;
 
 	mutex_lock(&apb_dma_lock);
 
@@ -82,9 +83,10 @@ static u32 tegra20_fuse_readl(const unsigned int offset)
 
 	dmaengine_submit(dma_desc);
 	dma_async_issue_pending(apb_dma_chan);
-	ret = wait_for_completion_timeout(&apb_dma_wait, msecs_to_jiffies(50));
+	time_left = wait_for_completion_timeout(&apb_dma_wait,
+						msecs_to_jiffies(50));
 
-	if (WARN(ret == 0, "apb read dma timed out"))
+	if (WARN(time_left == 0, "apb read dma timed out"))
 		dmaengine_terminate_all(apb_dma_chan);
 	else
 		val = *apb_buffer;

+ 17 - 6
drivers/soc/tegra/pmc.c

@@ -377,13 +377,10 @@ int tegra_pmc_cpu_remove_clamping(int cpuid)
 }
 #endif /* CONFIG_SMP */
 
-/**
- * tegra_pmc_restart() - reboot the system
- * @mode: which mode to reboot in
- * @cmd: reboot command
- */
-void tegra_pmc_restart(enum reboot_mode mode, const char *cmd)
+static int tegra_pmc_restart_notify(struct notifier_block *this,
+				    unsigned long action, void *data)
 {
+	const char *cmd = data;
 	u32 value;
 
 	value = tegra_pmc_readl(PMC_SCRATCH0);
@@ -405,8 +402,15 @@ void tegra_pmc_restart(enum reboot_mode mode, const char *cmd)
 	value = tegra_pmc_readl(0);
 	value |= 0x10;
 	tegra_pmc_writel(value, 0);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block tegra_pmc_restart_handler = {
+	.notifier_call = tegra_pmc_restart_notify,
+	.priority = 128,
+};
+
 static int powergate_show(struct seq_file *s, void *data)
 {
 	unsigned int i;
@@ -837,6 +841,13 @@ static int tegra_pmc_probe(struct platform_device *pdev)
 			return err;
 	}
 
+	err = register_restart_handler(&tegra_pmc_restart_handler);
+	if (err) {
+		dev_err(&pdev->dev, "unable to register restart handler, %d\n",
+			err);
+		return err;
+	}
+
 	return 0;
 }
 

+ 0 - 2
include/soc/tegra/pmc.h

@@ -26,8 +26,6 @@
 struct clk;
 struct reset_control;
 
-void tegra_pmc_restart(enum reboot_mode mode, const char *cmd);
-
 #ifdef CONFIG_PM_SLEEP
 enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void);
 void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode);