Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
e8684605
Commit
e8684605
authored
Mar 26, 2009
by
Ingo Molnar
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'timers/hpet' into timers/core
parents
a5ebc0b1
c23e253e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
67 additions
and
17 deletions
+67
-17
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+3
-1
arch/x86/kernel/hpet.c
arch/x86/kernel/hpet.c
+64
-16
No files found.
Documentation/kernel-parameters.txt
View file @
e8684605
...
...
@@ -492,10 +492,12 @@ and is between 256 and 4096 characters. It is defined in the file
Default: 64
hpet= [X86-32,HPET] option to control HPET usage
Format: { enable (default) | disable | force }
Format: { enable (default) | disable | force |
verbose }
disable: disable HPET and use PIT instead
force: allow force enabled of undocumented chips (ICH4,
VIA, nVidia)
verbose: show contents of HPET registers during setup
com20020= [HW,NET] ARCnet - COM20020 chipset
Format:
...
...
arch/x86/kernel/hpet.c
View file @
e8684605
...
...
@@ -80,6 +80,7 @@ static inline void hpet_clear_mapping(void)
*/
static
int
boot_hpet_disable
;
int
hpet_force_user
;
static
int
hpet_verbose
;
static
int
__init
hpet_setup
(
char
*
str
)
{
...
...
@@ -88,6 +89,8 @@ static int __init hpet_setup(char *str)
boot_hpet_disable
=
1
;
if
(
!
strncmp
(
"force"
,
str
,
5
))
hpet_force_user
=
1
;
if
(
!
strncmp
(
"verbose"
,
str
,
7
))
hpet_verbose
=
1
;
}
return
1
;
}
...
...
@@ -119,6 +122,43 @@ int is_hpet_enabled(void)
}
EXPORT_SYMBOL_GPL
(
is_hpet_enabled
);
static
void
_hpet_print_config
(
const
char
*
function
,
int
line
)
{
u32
i
,
timers
,
l
,
h
;
printk
(
KERN_INFO
"hpet: %s(%d):
\n
"
,
function
,
line
);
l
=
hpet_readl
(
HPET_ID
);
h
=
hpet_readl
(
HPET_PERIOD
);
timers
=
((
l
&
HPET_ID_NUMBER
)
>>
HPET_ID_NUMBER_SHIFT
)
+
1
;
printk
(
KERN_INFO
"hpet: ID: 0x%x, PERIOD: 0x%x
\n
"
,
l
,
h
);
l
=
hpet_readl
(
HPET_CFG
);
h
=
hpet_readl
(
HPET_STATUS
);
printk
(
KERN_INFO
"hpet: CFG: 0x%x, STATUS: 0x%x
\n
"
,
l
,
h
);
l
=
hpet_readl
(
HPET_COUNTER
);
h
=
hpet_readl
(
HPET_COUNTER
+
4
);
printk
(
KERN_INFO
"hpet: COUNTER_l: 0x%x, COUNTER_h: 0x%x
\n
"
,
l
,
h
);
for
(
i
=
0
;
i
<
timers
;
i
++
)
{
l
=
hpet_readl
(
HPET_Tn_CFG
(
i
));
h
=
hpet_readl
(
HPET_Tn_CFG
(
i
)
+
4
);
printk
(
KERN_INFO
"hpet: T%d: CFG_l: 0x%x, CFG_h: 0x%x
\n
"
,
i
,
l
,
h
);
l
=
hpet_readl
(
HPET_Tn_CMP
(
i
));
h
=
hpet_readl
(
HPET_Tn_CMP
(
i
)
+
4
);
printk
(
KERN_INFO
"hpet: T%d: CMP_l: 0x%x, CMP_h: 0x%x
\n
"
,
i
,
l
,
h
);
l
=
hpet_readl
(
HPET_Tn_ROUTE
(
i
));
h
=
hpet_readl
(
HPET_Tn_ROUTE
(
i
)
+
4
);
printk
(
KERN_INFO
"hpet: T%d ROUTE_l: 0x%x, ROUTE_h: 0x%x
\n
"
,
i
,
l
,
h
);
}
}
#define hpet_print_config() \
do { \
if (hpet_verbose) \
_hpet_print_config(__FUNCTION__, __LINE__); \
} while (0)
/*
* When the hpet driver (/dev/hpet) is enabled, we need to reserve
* timer 0 and timer 1 in case of RTC emulation.
...
...
@@ -191,27 +231,37 @@ static struct clock_event_device hpet_clockevent = {
.
rating
=
50
,
};
static
void
hpet_st
art
_counter
(
void
)
static
void
hpet_st
op
_counter
(
void
)
{
unsigned
long
cfg
=
hpet_readl
(
HPET_CFG
);
cfg
&=
~
HPET_CFG_ENABLE
;
hpet_writel
(
cfg
,
HPET_CFG
);
hpet_writel
(
0
,
HPET_COUNTER
);
hpet_writel
(
0
,
HPET_COUNTER
+
4
);
}
static
void
hpet_start_counter
(
void
)
{
unsigned
long
cfg
=
hpet_readl
(
HPET_CFG
);
cfg
|=
HPET_CFG_ENABLE
;
hpet_writel
(
cfg
,
HPET_CFG
);
}
static
void
hpet_restart_counter
(
void
)
{
hpet_stop_counter
();
hpet_start_counter
();
}
static
void
hpet_resume_device
(
void
)
{
force_hpet_resume
();
}
static
void
hpet_res
tart
_counter
(
void
)
static
void
hpet_res
ume
_counter
(
void
)
{
hpet_resume_device
();
hpet_start_counter
();
hpet_
re
start_counter
();
}
static
void
hpet_enable_legacy_int
(
void
)
...
...
@@ -259,29 +309,23 @@ static int hpet_setup_msi_irq(unsigned int irq);
static
void
hpet_set_mode
(
enum
clock_event_mode
mode
,
struct
clock_event_device
*
evt
,
int
timer
)
{
unsigned
long
cfg
,
cmp
,
now
;
unsigned
long
cfg
;
uint64_t
delta
;
switch
(
mode
)
{
case
CLOCK_EVT_MODE_PERIODIC
:
hpet_stop_counter
();
delta
=
((
uint64_t
)(
NSEC_PER_SEC
/
HZ
))
*
evt
->
mult
;
delta
>>=
evt
->
shift
;
now
=
hpet_readl
(
HPET_COUNTER
);
cmp
=
now
+
(
unsigned
long
)
delta
;
cfg
=
hpet_readl
(
HPET_Tn_CFG
(
timer
));
/* Make sure we use edge triggered interrupts */
cfg
&=
~
HPET_TN_LEVEL
;
cfg
|=
HPET_TN_ENABLE
|
HPET_TN_PERIODIC
|
HPET_TN_SETVAL
|
HPET_TN_32BIT
;
hpet_writel
(
cfg
,
HPET_Tn_CFG
(
timer
));
/*
* The first write after writing TN_SETVAL to the
* config register sets the counter value, the second
* write sets the period.
*/
hpet_writel
(
cmp
,
HPET_Tn_CMP
(
timer
));
udelay
(
1
);
hpet_writel
((
unsigned
long
)
delta
,
HPET_Tn_CMP
(
timer
));
hpet_start_counter
();
hpet_print_config
();
break
;
case
CLOCK_EVT_MODE_ONESHOT
:
...
...
@@ -308,6 +352,7 @@ static void hpet_set_mode(enum clock_event_mode mode,
irq_set_affinity
(
hdev
->
irq
,
cpumask_of
(
hdev
->
cpu
));
enable_irq
(
hdev
->
irq
);
}
hpet_print_config
();
break
;
}
}
...
...
@@ -526,6 +571,7 @@ static void hpet_msi_capability_lookup(unsigned int start_timer)
num_timers
=
((
id
&
HPET_ID_NUMBER
)
>>
HPET_ID_NUMBER_SHIFT
);
num_timers
++
;
/* Value read out starts from 0 */
hpet_print_config
();
hpet_devs
=
kzalloc
(
sizeof
(
struct
hpet_dev
)
*
num_timers
,
GFP_KERNEL
);
if
(
!
hpet_devs
)
...
...
@@ -695,7 +741,7 @@ static struct clocksource clocksource_hpet = {
.
mask
=
HPET_MASK
,
.
shift
=
HPET_SHIFT
,
.
flags
=
CLOCK_SOURCE_IS_CONTINUOUS
,
.
resume
=
hpet_res
tart
_counter
,
.
resume
=
hpet_res
ume
_counter
,
#ifdef CONFIG_X86_64
.
vread
=
vread_hpet
,
#endif
...
...
@@ -707,7 +753,7 @@ static int hpet_clocksource_register(void)
cycle_t
t1
;
/* Start the counter */
hpet_start_counter
();
hpet_
re
start_counter
();
/* Verify whether hpet counter works */
t1
=
read_hpet
();
...
...
@@ -793,6 +839,7 @@ int __init hpet_enable(void)
* information and the number of channels
*/
id
=
hpet_readl
(
HPET_ID
);
hpet_print_config
();
#ifdef CONFIG_HPET_EMULATE_RTC
/*
...
...
@@ -845,6 +892,7 @@ static __init int hpet_late_init(void)
return
-
ENODEV
;
hpet_reserve_platform_timers
(
hpet_readl
(
HPET_ID
));
hpet_print_config
();
for_each_online_cpu
(
cpu
)
{
hpet_cpuhp_notify
(
NULL
,
CPU_ONLINE
,
(
void
*
)(
long
)
cpu
);
...
...
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