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
powerpc
platforms
chrp
time.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
3
*
4
* Adapted for PowerPC (PReP) by Gary Thomas
5
* Modified by Cort Dougan (
[email protected]
).
6
* Copied and modified from arch/i386/kernel/time.c
7
*
8
*/
9
#include <linux/errno.h>
10
#include <linux/sched.h>
11
#include <linux/kernel.h>
12
#include <
linux/param.h
>
13
#include <linux/string.h>
14
#include <
linux/mm.h
>
15
#include <
linux/interrupt.h
>
16
#include <linux/time.h>
17
#include <linux/timex.h>
18
#include <
linux/kernel_stat.h
>
19
#include <
linux/mc146818rtc.h
>
20
#include <
linux/init.h
>
21
#include <
linux/bcd.h
>
22
#include <
linux/ioport.h
>
23
24
#include <asm/io.h>
25
#include <asm/nvram.h>
26
#include <asm/prom.h>
27
#include <asm/sections.h>
28
#include <asm/time.h>
29
30
extern
spinlock_t
rtc_lock
;
31
32
#define NVRAM_AS0 0x74
33
#define NVRAM_AS1 0x75
34
#define NVRAM_DATA 0x77
35
36
static
int
nvram_as1 =
NVRAM_AS1
;
37
static
int
nvram_as0 =
NVRAM_AS0
;
38
static
int
nvram_data =
NVRAM_DATA
;
39
40
long
__init
chrp_time_init
(
void
)
41
{
42
struct
device_node
*rtcs;
43
struct
resource
r;
44
int
base
;
45
46
rtcs =
of_find_compatible_node
(
NULL
,
"rtc"
,
"pnpPNP,b00"
);
47
if
(rtcs ==
NULL
)
48
rtcs =
of_find_compatible_node
(
NULL
,
"rtc"
,
"ds1385-rtc"
);
49
if
(rtcs ==
NULL
)
50
return
0;
51
if
(
of_address_to_resource
(rtcs, 0, &r)) {
52
of_node_put(rtcs);
53
return
0;
54
}
55
of_node_put(rtcs);
56
57
base = r.
start
;
58
nvram_as1 = 0;
59
nvram_as0 = base;
60
nvram_data = base + 1;
61
62
return
0;
63
}
64
65
int
chrp_cmos_clock_read
(
int
addr
)
66
{
67
if
(nvram_as1 != 0)
68
outb
(addr>>8, nvram_as1);
69
outb
(addr, nvram_as0);
70
return
(
inb
(nvram_data));
71
}
72
73
void
chrp_cmos_clock_write
(
unsigned
long
val
,
int
addr
)
74
{
75
if
(nvram_as1 != 0)
76
outb
(addr>>8, nvram_as1);
77
outb
(addr, nvram_as0);
78
outb
(val, nvram_data);
79
return
;
80
}
81
82
/*
83
* Set the hardware clock. -- Cort
84
*/
85
int
chrp_set_rtc_time
(
struct
rtc_time
*tmarg)
86
{
87
unsigned
char
save_control, save_freq_select;
88
struct
rtc_time
tm = *tmarg;
89
90
spin_lock(&rtc_lock);
91
92
save_control =
chrp_cmos_clock_read
(
RTC_CONTROL
);
/* tell the clock it's being set */
93
94
chrp_cmos_clock_write
((save_control|
RTC_SET
),
RTC_CONTROL
);
95
96
save_freq_select =
chrp_cmos_clock_read
(
RTC_FREQ_SELECT
);
/* stop and reset prescaler */
97
98
chrp_cmos_clock_write
((save_freq_select|
RTC_DIV_RESET2
),
RTC_FREQ_SELECT
);
99
100
if
(!(save_control &
RTC_DM_BINARY
) ||
RTC_ALWAYS_BCD
) {
101
tm.
tm_sec
=
bin2bcd
(tm.
tm_sec
);
102
tm.
tm_min
=
bin2bcd
(tm.
tm_min
);
103
tm.
tm_hour
=
bin2bcd
(tm.
tm_hour
);
104
tm.
tm_mon
=
bin2bcd
(tm.
tm_mon
);
105
tm.
tm_mday
=
bin2bcd
(tm.
tm_mday
);
106
tm.
tm_year
=
bin2bcd
(tm.
tm_year
);
107
}
108
chrp_cmos_clock_write
(tm.
tm_sec
,
RTC_SECONDS
);
109
chrp_cmos_clock_write
(tm.
tm_min
,
RTC_MINUTES
);
110
chrp_cmos_clock_write
(tm.
tm_hour
,
RTC_HOURS
);
111
chrp_cmos_clock_write
(tm.
tm_mon
,
RTC_MONTH
);
112
chrp_cmos_clock_write
(tm.
tm_mday
,
RTC_DAY_OF_MONTH
);
113
chrp_cmos_clock_write
(tm.
tm_year
,
RTC_YEAR
);
114
115
/* The following flags have to be released exactly in this order,
116
* otherwise the DS12887 (popular MC146818A clone with integrated
117
* battery and quartz) will not reset the oscillator and will not
118
* update precisely 500 ms later. You won't find this mentioned in
119
* the Dallas Semiconductor data sheets, but who believes data
120
* sheets anyway ... -- Markus Kuhn
121
*/
122
chrp_cmos_clock_write
(save_control,
RTC_CONTROL
);
123
chrp_cmos_clock_write
(save_freq_select,
RTC_FREQ_SELECT
);
124
125
spin_unlock(&rtc_lock);
126
return
0;
127
}
128
129
void
chrp_get_rtc_time
(
struct
rtc_time
*
tm
)
130
{
131
unsigned
int
year
, mon,
day
,
hour
,
min
,
sec
;
132
133
do
{
134
sec =
chrp_cmos_clock_read
(
RTC_SECONDS
);
135
min =
chrp_cmos_clock_read
(
RTC_MINUTES
);
136
hour =
chrp_cmos_clock_read
(
RTC_HOURS
);
137
day =
chrp_cmos_clock_read
(
RTC_DAY_OF_MONTH
);
138
mon =
chrp_cmos_clock_read
(
RTC_MONTH
);
139
year =
chrp_cmos_clock_read
(
RTC_YEAR
);
140
}
while
(sec !=
chrp_cmos_clock_read
(
RTC_SECONDS
));
141
142
if
(!(
chrp_cmos_clock_read
(
RTC_CONTROL
) &
RTC_DM_BINARY
) ||
RTC_ALWAYS_BCD
) {
143
sec =
bcd2bin
(sec);
144
min =
bcd2bin
(min);
145
hour =
bcd2bin
(hour);
146
day =
bcd2bin
(day);
147
mon =
bcd2bin
(mon);
148
year =
bcd2bin
(year);
149
}
150
if
(year < 70)
151
year += 100;
152
tm->
tm_sec
=
sec
;
153
tm->
tm_min
=
min
;
154
tm->
tm_hour
=
hour
;
155
tm->
tm_mday
=
day
;
156
tm->
tm_mon
= mon;
157
tm->
tm_year
=
year
;
158
}
Generated on Thu Jan 10 2013 12:53:35 for Linux Kernel by
1.8.2