1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (c) 2007 Simtec Electronics
4 *	Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2412 Power Manager low-level sleep support
7 */
8
9#include <linux/linkage.h>
10#include <asm/assembler.h>
11#include "map.h"
12
13#include "regs-irq.h"
14
15	.text
16
17	.global	s3c2412_sleep_enter
18
19s3c2412_sleep_enter:
20	mov	r0, #0			/* argument for coprocessors */
21	ldr	r1, =S3C2410_INTPND
22	ldr	r2, =S3C2410_SRCPND
23	ldr	r3, =S3C2410_EINTPEND
24
25	teq	r0, r0
26	bl	s3c2412_sleep_enter1
27	teq	pc, r0
28	bl	s3c2412_sleep_enter1
29
30	.align	5
31
32	/* this is called twice, first with the Z flag to ensure that the
33	 * instructions have been loaded into the cache, and the second
34	 * time to try and suspend the system.
35	*/
36s3c2412_sleep_enter1:
37	mcr	p15, 0, r0, c7, c10, 4
38	mcrne	p15, 0, r0, c7, c0, 4
39
40	/* if we return from here, it is because an interrupt was
41	 * active when we tried to shutdown. Try and ack the IRQ and
42	 * retry, as simply returning causes the system to lock.
43	*/
44
45	ldrne	r9, [r1]
46	strne	r9, [r1]
47	ldrne	r9, [r2]
48	strne	r9, [r2]
49	ldrne	r9, [r3]
50	strne	r9, [r3]
51	bne	s3c2412_sleep_enter1
52
53	ret	lr
54