Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
sparc
kernel
leon_pmc.c
Go to the documentation of this file.
1
/* leon_pmc.c: LEON Power-down cpu_idle() handler
2
*
3
* Copyright (C) 2011 Daniel Hellstrom (
[email protected]
) Aeroflex Gaisler AB
4
*/
5
6
#include <
linux/init.h
>
7
#include <
linux/pm.h
>
8
9
#include <
asm/leon_amba.h
>
10
#include <
asm/cpu_type.h
>
11
#include <
asm/leon.h
>
12
13
/* List of Systems that need fixup instructions around power-down instruction */
14
unsigned
int
pmc_leon_fixup_ids
[] = {
15
AEROFLEX_UT699
,
16
GAISLER_GR712RC
,
17
LEON4_NEXTREME1
,
18
0
19
};
20
21
int
pmc_leon_need_fixup
(
void
)
22
{
23
unsigned
int
systemid
=
amba_system_id
>> 16;
24
unsigned
int
*
id
;
25
26
id
= &
pmc_leon_fixup_ids
[0];
27
while
(*
id
!= 0) {
28
if
(*
id
== systemid)
29
return
1;
30
id
++;
31
}
32
33
return
0;
34
}
35
36
/*
37
* CPU idle callback function for systems that need some extra handling
38
* See .../arch/sparc/kernel/process.c
39
*/
40
void
pmc_leon_idle_fixup
(
void
)
41
{
42
/* Prepare an address to a non-cachable region. APB is always
43
* none-cachable. One instruction is executed after the Sleep
44
* instruction, we make sure to read the bus and throw away the
45
* value by accessing a non-cachable area, also we make sure the
46
* MMU does not get a TLB miss here by using the MMU BYPASS ASI.
47
*/
48
register
unsigned
int
address
= (
unsigned
int
)
leon3_irqctrl_regs
;
49
__asm__
__volatile__ (
50
"mov %%g0, %%asr19\n"
51
"lda [%0] %1, %%g0\n"
52
:
53
:
"r"
(address),
"i"
(
ASI_LEON_BYPASS
));
54
}
55
56
/*
57
* CPU idle callback function
58
* See .../arch/sparc/kernel/process.c
59
*/
60
void
pmc_leon_idle
(
void
)
61
{
62
/* For systems without power-down, this will be no-op */
63
__asm__
__volatile__ (
"mov %g0, %asr19\n\t"
);
64
}
65
66
/* Install LEON Power Down function */
67
static
int
__init
leon_pmc_install(
void
)
68
{
69
if
(
sparc_cpu_model
==
sparc_leon
) {
70
/* Assign power management IDLE handler */
71
if
(
pmc_leon_need_fixup
())
72
pm_idle
=
pmc_leon_idle_fixup
;
73
else
74
pm_idle
=
pmc_leon_idle
;
75
76
printk
(
KERN_INFO
"leon: power management initialized\n"
);
77
}
78
79
return
0;
80
}
81
82
/* This driver is not critical to the boot process, don't care
83
* if initialized late.
84
*/
85
late_initcall
(leon_pmc_install);
Generated on Thu Jan 10 2013 13:18:26 for Linux Kernel by
1.8.2