mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 16:37:50 +00:00
ARM: tegra: Core SoC changes for v4.2-rc1
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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJVU1HFAAoJEN0jrNd/PrOhZNQP/ji9c+i3NPHn8Ll1bd9G8ppB Mv3SCjRqen1FVgrjuduGGlw+d6iJxVQvYM9tZ09ciFBLEsYzardiPpWeTau7stbn AKehXQQLoaj8ZZDJta09aLSjwddm9OkYGfceRykPnRoSRNDiWxGA71KXiYTN3TxZ A1mEJ7oIUZhZvltcriNeU9R/54/slLq00tPaD6XsH32l6GTdlS591mDgPBVia8TC HkcbXhutHInXtaP0IAaWHYrS2hp0Gy5/bIabKgjmK1bd1tBgf8g3hxe1YkUIaeWf j9F3Pb6SV54GSTV0p6hDsX/FnD7j9/ly3XQasdMp/+YOMCG+RfQjPhri2q32NIBm QDeG7BYUQJ8ktAFuGgOiwxpp9plTUBSMDDYOraHSJf2FVqH2NTlLkm9vamm5d6wb edlkyTmy5xeUCX4+hADgEbSTxSagXzSiZ4mLPtCL656ASwGriEg/HoyVnzHWNvJa 6il5eEg6qaTYh2Ui+4z6BYZx8DQ8tQ51sg9lW/Y+QL71jopAHqS3wjnKJ/RlcePQ TD4tYhf6ALMLGZWGB/VYRwKPxYuI+owzf7P7mBzX0NtbY1PxsiQA2ximO7Y+XegE Ou2rO2lQVofH3WbzhfYgT4/+c0NtDpdI2FGsEMhsPYE3zLTyO+d8gsEQsI6oGkrU I/soe1xKK/4BZT6IZTP7 =BR2n -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
2516a932ef
9 changed files with 59 additions and 33 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue