Commit 2516a932 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'tegra-for-4.2-soc' of...

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
parents 94db5b98 7892158a
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "iomap.h" #include "iomap.h"
#include "irq.h" #include "irq.h"
#include "pm.h" #include "pm.h"
#include "reset.h"
#include "sleep.h" #include "sleep.h"
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
...@@ -70,15 +71,13 @@ static struct cpuidle_driver tegra_idle_driver = { ...@@ -70,15 +71,13 @@ static struct cpuidle_driver tegra_idle_driver = {
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
static int tegra20_reset_sleeping_cpu_1(void) static int tegra20_reset_sleeping_cpu_1(void)
{ {
int ret = 0; int ret = 0;
tegra_pen_lock(); tegra_pen_lock();
if (readl(pmc + PMC_SCRATCH41) == CPU_RESETTABLE) if (readb(tegra20_cpu1_resettable_status) == CPU_RESETTABLE)
tegra20_cpu_shutdown(1); tegra20_cpu_shutdown(1);
else else
ret = -EINVAL; ret = -EINVAL;
......
...@@ -169,10 +169,10 @@ after_errata: ...@@ -169,10 +169,10 @@ after_errata:
cmp r6, #TEGRA20 cmp r6, #TEGRA20
bne 1f bne 1f
/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
mov32 r5, TEGRA_PMC_BASE mov32 r5, TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET
mov r0, #0 mov r0, #CPU_NOT_RESETTABLE
cmp r10, #0 cmp r10, #0
strne r0, [r5, #PMC_SCRATCH41] strneb r0, [r5, #__tegra20_cpu1_resettable_status_offset]
1: 1:
#endif #endif
...@@ -281,6 +281,10 @@ __tegra_cpu_reset_handler_data: ...@@ -281,6 +281,10 @@ __tegra_cpu_reset_handler_data:
.rept TEGRA_RESET_DATA_SIZE .rept TEGRA_RESET_DATA_SIZE
.long 0 .long 0
.endr .endr
.globl __tegra20_cpu1_resettable_status_offset
.equ __tegra20_cpu1_resettable_status_offset, \
. - __tegra_cpu_reset_handler_start
.byte 0
.align L1_CACHE_SHIFT .align L1_CACHE_SHIFT
ENTRY(__tegra_cpu_reset_handler_end) ENTRY(__tegra_cpu_reset_handler_end)
...@@ -35,6 +35,7 @@ extern unsigned long __tegra_cpu_reset_handler_data[TEGRA_RESET_DATA_SIZE]; ...@@ -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_start(void);
void __tegra_cpu_reset_handler(void); void __tegra_cpu_reset_handler(void);
void __tegra20_cpu1_resettable_status_offset(void);
void __tegra_cpu_reset_handler_end(void); void __tegra_cpu_reset_handler_end(void);
void tegra_secondary_startup(void); void tegra_secondary_startup(void);
...@@ -47,6 +48,9 @@ void tegra_secondary_startup(void); ...@@ -47,6 +48,9 @@ void tegra_secondary_startup(void);
(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \ (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_data[TEGRA_RESET_MASK_LP2] - \
(u32)__tegra_cpu_reset_handler_start))) (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 #endif
#define tegra_cpu_reset_handler_offset \ #define tegra_cpu_reset_handler_offset \
......
...@@ -97,9 +97,10 @@ ENDPROC(tegra20_hotplug_shutdown) ...@@ -97,9 +97,10 @@ ENDPROC(tegra20_hotplug_shutdown)
ENTRY(tegra20_cpu_shutdown) ENTRY(tegra20_cpu_shutdown)
cmp r0, #0 cmp r0, #0
reteq lr @ must not be called for CPU 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 mov r12, #CPU_RESETTABLE
str r12, [r1] strb r12, [r1, r2]
cpu_to_halt_reg r1, r0 cpu_to_halt_reg r1, r0
ldr r3, =TEGRA_FLOW_CTRL_VIRT ldr r3, =TEGRA_FLOW_CTRL_VIRT
...@@ -182,38 +183,41 @@ ENDPROC(tegra_pen_unlock) ...@@ -182,38 +183,41 @@ ENDPROC(tegra_pen_unlock)
/* /*
* tegra20_cpu_clear_resettable(void) * 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. * it is expected that the secondary CPU will be idle soon.
*/ */
ENTRY(tegra20_cpu_clear_resettable) 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 mov r12, #CPU_NOT_RESETTABLE
str r12, [r1] strb r12, [r1, r2]
ret lr ret lr
ENDPROC(tegra20_cpu_clear_resettable) ENDPROC(tegra20_cpu_clear_resettable)
/* /*
* tegra20_cpu_set_resettable_soon(void) * 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. * it is expected that the secondary CPU will be idle soon.
*/ */
ENTRY(tegra20_cpu_set_resettable_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 mov r12, #CPU_RESETTABLE_SOON
str r12, [r1] strb r12, [r1, r2]
ret lr ret lr
ENDPROC(tegra20_cpu_set_resettable_soon) ENDPROC(tegra20_cpu_set_resettable_soon)
/* /*
* tegra20_cpu_is_resettable_soon(void) * 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. * set because it is expected that the secondary CPU will be idle soon.
*/ */
ENTRY(tegra20_cpu_is_resettable_soon) ENTRY(tegra20_cpu_is_resettable_soon)
mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41 mov32 r1, TEGRA_IRAM_RESET_BASE_VIRT
ldr r12, [r1] ldr r2, =__tegra20_cpu1_resettable_status_offset
ldrb r12, [r1, r2]
cmp r12, #CPU_RESETTABLE_SOON cmp r12, #CPU_RESETTABLE_SOON
moveq r0, #1 moveq r0, #1
movne r0, #0 movne r0, #0
...@@ -256,9 +260,10 @@ ENTRY(tegra20_sleep_cpu_secondary_finish) ...@@ -256,9 +260,10 @@ ENTRY(tegra20_sleep_cpu_secondary_finish)
mov r0, #TEGRA_FLUSH_CACHE_LOUIS mov r0, #TEGRA_FLUSH_CACHE_LOUIS
bl tegra_disable_clean_inv_dcache 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 mov r3, #CPU_RESETTABLE
str r3, [r0] strb r3, [r0, r4]
bl tegra_cpu_do_idle bl tegra_cpu_do_idle
...@@ -274,10 +279,10 @@ ENTRY(tegra20_sleep_cpu_secondary_finish) ...@@ -274,10 +279,10 @@ ENTRY(tegra20_sleep_cpu_secondary_finish)
bl tegra_pen_lock bl tegra_pen_lock
mov32 r3, TEGRA_PMC_VIRT mov32 r0, TEGRA_IRAM_RESET_BASE_VIRT
add r0, r3, #PMC_SCRATCH41 ldr r4, =__tegra20_cpu1_resettable_status_offset
mov r3, #CPU_NOT_RESETTABLE mov r3, #CPU_NOT_RESETTABLE
str r3, [r0] strb r3, [r0, r4]
bl tegra_pen_unlock bl tegra_pen_unlock
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#define __MACH_TEGRA_SLEEP_H #define __MACH_TEGRA_SLEEP_H
#include "iomap.h" #include "iomap.h"
#include "irammap.h"
#define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \ #define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \
+ IO_CPU_VIRT) + IO_CPU_VIRT)
...@@ -29,6 +30,9 @@ ...@@ -29,6 +30,9 @@
+ IO_APB_VIRT) + IO_APB_VIRT)
#define TEGRA_PMC_VIRT (TEGRA_PMC_BASE - IO_APB_PHYS + 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 */ /* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */
#define PMC_SCRATCH37 0x130 #define PMC_SCRATCH37 0x130
#define PMC_SCRATCH38 0x134 #define PMC_SCRATCH38 0x134
......
...@@ -163,6 +163,5 @@ DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)") ...@@ -163,6 +163,5 @@ DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
.init_irq = tegra_dt_init_irq, .init_irq = tegra_dt_init_irq,
.init_machine = tegra_dt_init, .init_machine = tegra_dt_init,
.init_late = tegra_dt_init_late, .init_late = tegra_dt_init_late,
.restart = tegra_pmc_restart,
.dt_compat = tegra_dt_board_compat, .dt_compat = tegra_dt_board_compat,
MACHINE_END MACHINE_END
...@@ -59,6 +59,7 @@ static u32 tegra20_fuse_readl(const unsigned int offset) ...@@ -59,6 +59,7 @@ static u32 tegra20_fuse_readl(const unsigned int offset)
int ret; int ret;
u32 val = 0; u32 val = 0;
struct dma_async_tx_descriptor *dma_desc; struct dma_async_tx_descriptor *dma_desc;
unsigned long time_left;
mutex_lock(&apb_dma_lock); mutex_lock(&apb_dma_lock);
...@@ -82,9 +83,10 @@ static u32 tegra20_fuse_readl(const unsigned int offset) ...@@ -82,9 +83,10 @@ static u32 tegra20_fuse_readl(const unsigned int offset)
dmaengine_submit(dma_desc); dmaengine_submit(dma_desc);
dma_async_issue_pending(apb_dma_chan); 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); dmaengine_terminate_all(apb_dma_chan);
else else
val = *apb_buffer; val = *apb_buffer;
......
...@@ -377,13 +377,10 @@ int tegra_pmc_cpu_remove_clamping(int cpuid) ...@@ -377,13 +377,10 @@ int tegra_pmc_cpu_remove_clamping(int cpuid)
} }
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
/** static int tegra_pmc_restart_notify(struct notifier_block *this,
* tegra_pmc_restart() - reboot the system unsigned long action, void *data)
* @mode: which mode to reboot in
* @cmd: reboot command
*/
void tegra_pmc_restart(enum reboot_mode mode, const char *cmd)
{ {
const char *cmd = data;
u32 value; u32 value;
value = tegra_pmc_readl(PMC_SCRATCH0); value = tegra_pmc_readl(PMC_SCRATCH0);
...@@ -405,8 +402,15 @@ void tegra_pmc_restart(enum reboot_mode mode, const char *cmd) ...@@ -405,8 +402,15 @@ void tegra_pmc_restart(enum reboot_mode mode, const char *cmd)
value = tegra_pmc_readl(0); value = tegra_pmc_readl(0);
value |= 0x10; value |= 0x10;
tegra_pmc_writel(value, 0); 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) static int powergate_show(struct seq_file *s, void *data)
{ {
unsigned int i; unsigned int i;
...@@ -837,6 +841,13 @@ static int tegra_pmc_probe(struct platform_device *pdev) ...@@ -837,6 +841,13 @@ static int tegra_pmc_probe(struct platform_device *pdev)
return err; 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; return 0;
} }
......
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
struct clk; struct clk;
struct reset_control; struct reset_control;
void tegra_pmc_restart(enum reboot_mode mode, const char *cmd);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void); enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void);
void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode); void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment