Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
535c4879
Commit
535c4879
authored
Sep 03, 2003
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ppc64: rtas rtc fixes from Todd Inglett
parent
7430b429
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
94 additions
and
17 deletions
+94
-17
arch/ppc64/kernel/chrp_setup.c
arch/ppc64/kernel/chrp_setup.c
+2
-1
arch/ppc64/kernel/rtas.c
arch/ppc64/kernel/rtas.c
+21
-0
arch/ppc64/kernel/rtc.c
arch/ppc64/kernel/rtc.c
+64
-16
include/asm-ppc64/rtas.h
include/asm-ppc64/rtas.h
+7
-0
No files found.
arch/ppc64/kernel/chrp_setup.c
View file @
535c4879
...
...
@@ -72,6 +72,7 @@ extern void openpic_init_IRQ(void);
extern
void
find_and_init_phbs
(
void
);
extern
void
pSeries_get_boot_time
(
struct
rtc_time
*
rtc_time
);
extern
void
pSeries_get_rtc_time
(
struct
rtc_time
*
rtc_time
);
extern
int
pSeries_set_rtc_time
(
struct
rtc_time
*
rtc_time
);
void
pSeries_calibrate_decr
(
void
);
...
...
@@ -256,7 +257,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md
.
power_off
=
rtas_power_off
;
ppc_md
.
halt
=
rtas_halt
;
ppc_md
.
get_boot_time
=
pSeries_get_
rtc
_time
;
ppc_md
.
get_boot_time
=
pSeries_get_
boot
_time
;
ppc_md
.
get_rtc_time
=
pSeries_get_rtc_time
;
ppc_md
.
set_rtc_time
=
pSeries_set_rtc_time
;
ppc_md
.
calibrate_decr
=
pSeries_calibrate_decr
;
...
...
arch/ppc64/kernel/rtas.c
View file @
535c4879
...
...
@@ -24,6 +24,7 @@
#include <asm/machdep.h>
#include <asm/paca.h>
#include <asm/page.h>
#include <asm/param.h>
#include <asm/system.h>
#include <asm/abs_addr.h>
#include <asm/udbg.h>
...
...
@@ -178,6 +179,26 @@ rtas_call(int token, int nargs, int nret,
return
(
ulong
)((
nret
>
0
)
?
rtas_args
->
rets
[
0
]
:
0
);
}
/* Given an RTAS status code of 990n compute the hinted delay of 10^n
* (last digit) milliseconds. For now we bound at n=3 (1 sec).
*/
unsigned
int
rtas_extended_busy_delay_time
(
int
status
)
{
int
order
=
status
-
9900
;
unsigned
int
ms
;
if
(
order
<
0
)
order
=
0
;
/* RTC depends on this for -2 clock busy */
else
if
(
order
>
3
)
order
=
3
;
/* bound */
/* Use microseconds for reasonable accuracy */
for
(
ms
=
1000
;
order
>
0
;
order
--
)
ms
=
ms
*
10
;
return
ms
/
(
1000000
/
HZ
);
/* round down is fine */
}
#define FLASH_BLOCK_LIST_VERSION (1UL)
static
void
rtas_flash_firmware
(
void
)
...
...
arch/ppc64/kernel/rtc.c
View file @
535c4879
...
...
@@ -35,6 +35,7 @@
#include <linux/spinlock.h>
#include <linux/bcd.h>
#include <asm/hardirq.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
...
...
@@ -340,20 +341,63 @@ void iSeries_get_boot_time(struct rtc_time *tm)
#endif
#ifdef CONFIG_PPC_PSERIES
void
pSeries_get_rtc_time
(
struct
rtc_time
*
rtc_tm
)
#define MAX_RTC_WAIT 5000
/* 5 sec */
#define RTAS_CLOCK_BUSY (-2)
void
pSeries_get_boot_time
(
struct
rtc_time
*
rtc_tm
)
{
unsigned
long
ret
[
8
];
int
error
;
int
count
;
int
error
,
wait_time
;
unsigned
long
max_wait_tb
;
/*
* error -2 is clock busy, we keep retrying a few times to see
* if it will come good -- paulus
max_wait_tb
=
__get_tb
()
+
tb_ticks_per_usec
*
1000
*
MAX_RTC_WAIT
;
do
{
error
=
rtas_call
(
rtas_token
(
"get-time-of-day"
),
0
,
8
,
(
void
*
)
&
ret
);
if
(
error
==
RTAS_CLOCK_BUSY
||
rtas_is_extended_busy
(
error
))
{
wait_time
=
rtas_extended_busy_delay_time
(
error
);
/* This is boot time so we spin. */
udelay
(
wait_time
*
1000
);
error
=
RTAS_CLOCK_BUSY
;
}
}
while
(
error
==
RTAS_CLOCK_BUSY
&&
(
__get_tb
()
<
max_wait_tb
));
if
(
error
!=
0
)
{
printk
(
KERN_WARNING
"error: reading the clock failed (%d)
\n
"
,
error
);
return
;
}
rtc_tm
->
tm_sec
=
ret
[
5
];
rtc_tm
->
tm_min
=
ret
[
4
];
rtc_tm
->
tm_hour
=
ret
[
3
];
rtc_tm
->
tm_mday
=
ret
[
2
];
rtc_tm
->
tm_mon
=
ret
[
1
]
-
1
;
rtc_tm
->
tm_year
=
ret
[
0
]
-
1900
;
}
/* NOTE: get_rtc_time will get an error if executed in interrupt context
* and if a delay is needed to read the clock. In this case we just
* silently return without updating rtc_tm.
*/
count
=
0
;
void
pSeries_get_rtc_time
(
struct
rtc_time
*
rtc_tm
)
{
unsigned
long
ret
[
8
];
int
error
,
wait_time
;
unsigned
long
max_wait_tb
;
max_wait_tb
=
__get_tb
()
+
tb_ticks_per_usec
*
1000
*
MAX_RTC_WAIT
;
do
{
error
=
rtas_call
(
rtas_token
(
"get-time-of-day"
),
0
,
8
,
(
void
*
)
&
ret
);
}
while
(
error
==
-
2
&&
++
count
<
1000
);
if
(
error
==
RTAS_CLOCK_BUSY
||
rtas_is_extended_busy
(
error
))
{
if
(
in_interrupt
())
{
printk
(
KERN_WARNING
"error: reading clock would delay interrupt
\n
"
);
return
;
/* delay not allowed */
}
wait_time
=
rtas_extended_busy_delay_time
(
error
);
set_current_state
(
TASK_INTERRUPTIBLE
);
schedule_timeout
(
wait_time
);
error
=
RTAS_CLOCK_BUSY
;
}
}
while
(
error
==
RTAS_CLOCK_BUSY
&&
(
__get_tb
()
<
max_wait_tb
));
if
(
error
!=
0
)
{
printk
(
KERN_WARNING
"error: reading the clock failed (%d)
\n
"
,
...
...
@@ -371,20 +415,24 @@ void pSeries_get_rtc_time(struct rtc_time *rtc_tm)
int
pSeries_set_rtc_time
(
struct
rtc_time
*
tm
)
{
int
error
;
int
count
;
int
error
,
wait_time
;
unsigned
long
max_wait_tb
;
/*
* error -2 is clock busy, we keep retrying a few times to see
* if it will come good -- paulus
*/
count
=
0
;
max_wait_tb
=
__get_tb
()
+
tb_ticks_per_usec
*
1000
*
MAX_RTC_WAIT
;
do
{
error
=
rtas_call
(
rtas_token
(
"set-time-of-day"
),
7
,
1
,
NULL
,
tm
->
tm_year
+
1900
,
tm
->
tm_mon
+
1
,
tm
->
tm_mday
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
,
0
);
}
while
(
error
==
-
2
&&
++
count
<
1000
);
if
(
error
==
RTAS_CLOCK_BUSY
||
rtas_is_extended_busy
(
error
))
{
if
(
in_interrupt
())
return
1
;
/* probably decrementer */
wait_time
=
rtas_extended_busy_delay_time
(
error
);
set_current_state
(
TASK_INTERRUPTIBLE
);
schedule_timeout
(
wait_time
);
error
=
RTAS_CLOCK_BUSY
;
}
}
while
(
error
==
RTAS_CLOCK_BUSY
&&
(
__get_tb
()
<
max_wait_tb
));
if
(
error
!=
0
)
printk
(
KERN_WARNING
"error: setting the clock failed (%d)
\n
"
,
...
...
include/asm-ppc64/rtas.h
View file @
535c4879
...
...
@@ -166,6 +166,13 @@ extern void rtas_restart(char *cmd);
extern
void
rtas_power_off
(
void
);
extern
void
rtas_halt
(
void
);
/* Given an RTAS status code of 9900..9905 compute the hinted delay */
unsigned
int
rtas_extended_busy_delay_time
(
int
status
);
static
inline
int
rtas_is_extended_busy
(
int
status
)
{
return
status
>=
9900
&&
status
<=
9909
;
}
/* Some RTAS ops require a data buffer and that buffer must be < 4G.
* Rather than having a memory allocator, just use this buffer
* (get the lock first), make the RTAS call. Copy the data instead
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment