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
Kirill Smelkov
linux
Commits
ee5caf0e
Commit
ee5caf0e
authored
Jun 29, 2006
by
David S. Miller
Committed by
David S. Miller
Jun 29, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SPARC]: Convert clock drivers to of_driver framework.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
36a59bd8
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
94 additions
and
265 deletions
+94
-265
arch/sparc/kernel/time.c
arch/sparc/kernel/time.c
+40
-69
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci.c
+0
-2
arch/sparc64/kernel/sbus.c
arch/sparc64/kernel/sbus.c
+0
-2
arch/sparc64/kernel/time.c
arch/sparc64/kernel/time.c
+54
-192
No files found.
arch/sparc/kernel/time.c
View file @
ee5caf0e
...
...
@@ -42,6 +42,7 @@
#include <asm/sun4paddr.h>
#include <asm/page.h>
#include <asm/pcic.h>
#include <asm/of_device.h>
extern
unsigned
long
wall_jiffies
;
...
...
@@ -273,83 +274,31 @@ static __inline__ void sun4_clock_probe(void)
#endif
}
/* Probe for the mostek real time clock chip. */
static
__inline__
void
clock_probe
(
void
)
static
int
__devinit
clock_probe
(
struct
of_device
*
op
,
const
struct
of_device_id
*
match
)
{
struct
linux_prom_registers
clk_reg
[
2
];
char
model
[
128
];
register
int
node
,
cpuunit
,
bootbus
;
struct
resource
r
;
cpuunit
=
bootbus
=
0
;
memset
(
&
r
,
0
,
sizeof
(
r
));
/* Determine the correct starting PROM node for the probe. */
node
=
prom_getchild
(
prom_root_node
);
switch
(
sparc_cpu_model
)
{
case
sun4c
:
break
;
case
sun4m
:
node
=
prom_getchild
(
prom_searchsiblings
(
node
,
"obio"
));
break
;
case
sun4d
:
node
=
prom_getchild
(
bootbus
=
prom_searchsiblings
(
prom_getchild
(
cpuunit
=
prom_searchsiblings
(
node
,
"cpu-unit"
)),
"bootbus"
));
break
;
default:
prom_printf
(
"CLOCK: Unsupported architecture!
\n
"
);
prom_halt
();
}
struct
device_node
*
dp
=
op
->
node
;
char
*
model
=
of_get_property
(
dp
,
"model"
,
NULL
);
/* Find the PROM node describing the real time clock. */
sp_clock_typ
=
MSTK_INVALID
;
node
=
prom_searchsiblings
(
node
,
"eeprom"
);
if
(
!
node
)
{
prom_printf
(
"CLOCK: No clock found!
\n
"
);
prom_halt
();
}
if
(
!
model
)
return
-
ENODEV
;
/* Get the model name and setup everything up. */
model
[
0
]
=
'\0'
;
prom_getstring
(
node
,
"model"
,
model
,
sizeof
(
model
));
if
(
strcmp
(
model
,
"mk48t02"
)
==
0
)
{
if
(
!
strcmp
(
model
,
"mk48t02"
))
{
sp_clock_typ
=
MSTK48T02
;
if
(
prom_getproperty
(
node
,
"reg"
,
(
char
*
)
clk_reg
,
sizeof
(
clk_reg
))
==
-
1
)
{
prom_printf
(
"clock_probe: FAILED!
\n
"
);
prom_halt
();
}
if
(
sparc_cpu_model
==
sun4d
)
prom_apply_generic_ranges
(
bootbus
,
cpuunit
,
clk_reg
,
1
);
else
prom_apply_obio_ranges
(
clk_reg
,
1
);
/* Map the clock register io area read-only */
r
.
flags
=
clk_reg
[
0
].
which_io
;
r
.
start
=
clk_reg
[
0
].
phys_addr
;
mstk48t02_regs
=
sbus_ioremap
(
&
r
,
0
,
sizeof
(
struct
mostek48t02
),
"mk48t02"
);
mstk48t02_regs
=
of_ioremap
(
&
op
->
resource
[
0
],
0
,
sizeof
(
struct
mostek48t02
),
"mk48t02"
);
mstk48t08_regs
=
NULL
;
/* To catch weirdness */
}
else
if
(
strcmp
(
model
,
"mk48t08"
)
==
0
)
{
}
else
if
(
!
strcmp
(
model
,
"mk48t08"
)
)
{
sp_clock_typ
=
MSTK48T08
;
if
(
prom_getproperty
(
node
,
"reg"
,
(
char
*
)
clk_reg
,
sizeof
(
clk_reg
))
==
-
1
)
{
prom_printf
(
"clock_probe: FAILED!
\n
"
);
prom_halt
();
}
if
(
sparc_cpu_model
==
sun4d
)
prom_apply_generic_ranges
(
bootbus
,
cpuunit
,
clk_reg
,
1
);
else
prom_apply_obio_ranges
(
clk_reg
,
1
);
/* Map the clock register io area read-only */
/* XXX r/o attribute is somewhere in r.flags */
r
.
flags
=
clk_reg
[
0
].
which_io
;
r
.
start
=
clk_reg
[
0
].
phys_addr
;
mstk48t08_regs
=
sbus_ioremap
(
&
r
,
0
,
sizeof
(
struct
mostek48t08
),
"mk48t08"
);
mstk48t08_regs
=
of_ioremap
(
&
op
->
resource
[
0
],
0
,
sizeof
(
struct
mostek48t08
),
"mk48t08"
);
mstk48t02_regs
=
&
mstk48t08_regs
->
regs
;
}
else
{
prom_printf
(
"CLOCK: Unknown model name '%s'
\n
"
,
model
);
prom_halt
();
}
}
else
return
-
ENODEV
;
/* Report a low battery voltage condition. */
if
(
has_low_battery
())
...
...
@@ -358,6 +307,28 @@ static __inline__ void clock_probe(void)
/* Kick start the clock if it is completely stopped. */
if
(
mostek_read
(
mstk48t02_regs
+
MOSTEK_SEC
)
&
MSTK_STOP
)
kick_start_clock
();
return
0
;
}
static
struct
of_device_id
clock_match
[]
=
{
{
.
name
=
"eeprom"
,
},
{},
};
static
struct
of_platform_driver
clock_driver
=
{
.
name
=
"clock"
,
.
match_table
=
clock_match
,
.
probe
=
clock_probe
,
};
/* Probe for the mostek real time clock chip. */
static
void
clock_init
(
void
)
{
of_register_driver
(
&
clock_driver
,
&
of_bus_type
);
}
void
__init
sbus_time_init
(
void
)
...
...
@@ -376,7 +347,7 @@ void __init sbus_time_init(void)
if
(
ARCH_SUN4
)
sun4_clock_probe
();
else
clock_
probe
();
clock_
init
();
sparc_init_timers
(
timer_interrupt
);
...
...
arch/sparc64/kernel/pci.c
View file @
ee5caf0e
...
...
@@ -307,7 +307,6 @@ static void __init pci_scan_each_controller_bus(void)
p
->
scan_bus
(
p
);
}
extern
void
clock_probe
(
void
);
extern
void
power_init
(
void
);
static
int
__init
pcibios_init
(
void
)
...
...
@@ -320,7 +319,6 @@ static int __init pcibios_init(void)
isa_init
();
ebus_init
();
clock_probe
();
power_init
();
return
0
;
...
...
arch/sparc64/kernel/sbus.c
View file @
ee5caf0e
...
...
@@ -1267,8 +1267,6 @@ int __init sbus_arch_preinit(void)
void
__init
sbus_arch_postinit
(
void
)
{
extern
void
firetruck_init
(
void
);
extern
void
clock_probe
(
void
);
firetruck_init
();
clock_probe
();
}
arch/sparc64/kernel/time.c
View file @
ee5caf0e
...
...
@@ -770,237 +770,99 @@ static int __init clock_model_matches(char *model)
return
1
;
}
static
void
__init
__clock_assign_common
(
void
__iomem
*
addr
,
char
*
model
)
static
int
__devinit
clock_probe
(
struct
of_device
*
op
,
const
struct
of_device_id
*
match
)
{
if
(
model
[
5
]
==
'0'
&&
model
[
6
]
==
'2'
)
{
mstk48t02_regs
=
addr
;
}
else
if
(
model
[
5
]
==
'0'
&&
model
[
6
]
==
'8'
)
{
mstk48t08_regs
=
addr
;
mstk48t02_regs
=
mstk48t08_regs
+
MOSTEK_48T08_48T02
;
}
else
{
mstk48t59_regs
=
addr
;
mstk48t02_regs
=
mstk48t59_regs
+
MOSTEK_48T59_48T02
;
}
}
static
void
__init
clock_assign_clk_reg
(
struct
linux_prom_registers
*
clk_reg
,
char
*
model
)
{
unsigned
long
addr
;
struct
device_node
*
dp
=
op
->
node
;
char
*
model
=
of_get_property
(
dp
,
"model"
,
NULL
);
unsigned
long
size
,
flags
;
void
__iomem
*
regs
;
addr
=
((
unsigned
long
)
clk_reg
[
0
].
phys_addr
|
(((
unsigned
long
)
clk_reg
[
0
].
which_io
)
<<
32UL
));
__clock_assign_common
((
void
__iomem
*
)
addr
,
model
);
}
static
int
__init
clock_probe_central
(
void
)
{
struct
linux_prom_registers
clk_reg
[
2
],
*
pr
;
struct
device_node
*
dp
;
char
*
model
;
if
(
!
central_bus
)
return
0
;
/* Get Central FHC's prom node. */
dp
=
central_bus
->
child
->
prom_node
;
/* Then get the first child device below it. */
dp
=
dp
->
child
;
while
(
dp
)
{
model
=
of_get_property
(
dp
,
"model"
,
NULL
);
if
(
!
model
||
!
clock_model_matches
(
model
))
goto
next_sibling
;
pr
=
of_get_property
(
dp
,
"reg"
,
NULL
);
memcpy
(
clk_reg
,
pr
,
sizeof
(
clk_reg
));
apply_fhc_ranges
(
central_bus
->
child
,
clk_reg
,
1
);
apply_central_ranges
(
central_bus
,
clk_reg
,
1
);
clock_assign_clk_reg
(
clk_reg
,
model
);
return
1
;
next_sibling:
dp
=
dp
->
sibling
;
}
if
(
!
model
||
!
clock_model_matches
(
model
))
return
-
ENODEV
;
return
0
;
}
size
=
(
op
->
resource
[
0
].
end
-
op
->
resource
[
0
].
start
)
+
1
;
regs
=
of_ioremap
(
&
op
->
resource
[
0
],
0
,
size
,
"clock"
);
if
(
!
regs
)
return
-
ENOMEM
;
#ifdef CONFIG_PCI
static
void
__init
clock_isa_ebus_assign_regs
(
struct
resource
*
res
,
char
*
model
)
{
if
(
!
strcmp
(
model
,
"ds1287"
)
||
!
strcmp
(
model
,
"m5819"
)
||
!
strcmp
(
model
,
"m5819p"
)
||
!
strcmp
(
model
,
"m5823"
))
{
ds1287_regs
=
res
->
start
;
ds1287_regs
=
(
unsigned
long
)
regs
;
}
else
if
(
model
[
5
]
==
'0'
&&
model
[
6
]
==
'2'
)
{
mstk48t02_regs
=
regs
;
}
else
if
(
model
[
5
]
==
'0'
&&
model
[
6
]
==
'8'
)
{
mstk48t08_regs
=
regs
;
mstk48t02_regs
=
mstk48t08_regs
+
MOSTEK_48T08_48T02
;
}
else
{
mstk48t59_regs
=
(
void
__iomem
*
)
res
->
start
;
mstk48t59_regs
=
regs
;
mstk48t02_regs
=
mstk48t59_regs
+
MOSTEK_48T59_48T02
;
}
}
static
int
__init
clock_probe_one_ebus_dev
(
struct
linux_ebus_device
*
edev
)
{
struct
device_node
*
dp
=
edev
->
prom_node
;
char
*
model
;
model
=
of_get_property
(
dp
,
"model"
,
NULL
);
if
(
!
clock_model_matches
(
model
))
return
0
;
clock_isa_ebus_assign_regs
(
&
edev
->
resource
[
0
],
model
);
printk
(
KERN_INFO
"%s: Clock regs at %p
\n
"
,
dp
->
full_name
,
regs
);
return
1
;
}
static
int
__init
clock_probe_ebus
(
void
)
{
struct
linux_ebus
*
ebus
;
local_irq_save
(
flags
);
for_each_ebus
(
ebus
)
{
struct
linux_ebus_device
*
edev
;
if
(
mstk48t02_regs
!=
NULL
)
{
/* Report a low battery voltage condition. */
if
(
has_low_battery
())
prom_printf
(
"NVRAM: Low battery voltage!
\n
"
);
for_each_ebusdev
(
edev
,
ebus
)
{
if
(
clock_probe_one_ebus_dev
(
edev
))
return
1
;
}
/* Kick start the clock if it is completely stopped. */
if
(
mostek_read
(
mstk48t02_regs
+
MOSTEK_SEC
)
&
MSTK_STOP
)
kick_start_clock
();
}
return
0
;
}
static
int
__init
clock_probe_one_isa_dev
(
struct
sparc_isa_device
*
idev
)
{
struct
device_node
*
dp
=
idev
->
prom_node
;
char
*
model
;
model
=
of_get_property
(
dp
,
"model"
,
NULL
);
if
(
!
clock_model_matches
(
model
))
return
0
;
clock_isa_ebus_assign_regs
(
&
idev
->
resource
,
model
);
return
1
;
}
static
int
__init
clock_probe_isa
(
void
)
{
struct
sparc_isa_bridge
*
isa_br
;
for_each_isa
(
isa_br
)
{
struct
sparc_isa_device
*
isa_dev
;
for_each_isadev
(
isa_dev
,
isa_br
)
{
if
(
clock_probe_one_isa_dev
(
isa_dev
))
return
1
;
}
}
set_system_time
();
local_irq_restore
(
flags
);
return
0
;
}
#endif
/* CONFIG_PCI */
#ifdef CONFIG_SBUS
static
int
__init
clock_probe_one_sbus_dev
(
struct
sbus_bus
*
sbus
,
struct
sbus_dev
*
sdev
)
{
struct
resource
*
res
;
char
model
[
64
];
void
__iomem
*
addr
;
prom_getstring
(
sdev
->
prom_node
,
"model"
,
model
,
sizeof
(
model
));
if
(
!
clock_model_matches
(
model
))
return
0
;
res
=
&
sdev
->
resource
[
0
];
addr
=
sbus_ioremap
(
res
,
0
,
0x800UL
,
"eeprom"
);
__clock_assign_common
(
addr
,
model
);
return
1
;
}
static
int
__init
clock_probe_sbus
(
void
)
{
struct
sbus_bus
*
sbus
;
for_each_sbus
(
sbus
)
{
struct
sbus_dev
*
sdev
;
for_each_sbusdev
(
sdev
,
sbus
)
{
if
(
clock_probe_one_sbus_dev
(
sbus
,
sdev
))
return
1
;
}
}
static
struct
of_device_id
clock_match
[]
=
{
{
.
name
=
"eeprom"
,
},
{
.
name
=
"rtc"
,
},
{},
};
return
0
;
}
#endif
static
struct
of_platform_driver
clock_driver
=
{
.
name
=
"clock"
,
.
match_table
=
clock_match
,
.
probe
=
clock_probe
,
};
void
__init
clock_probe
(
void
)
static
int
__init
clock_init
(
void
)
{
static
int
invoked
;
unsigned
long
flags
;
if
(
invoked
)
return
;
invoked
=
1
;
if
(
this_is_starfire
)
{
xtime
.
tv_sec
=
starfire_get_time
();
xtime
.
tv_nsec
=
(
INITIAL_JIFFIES
%
HZ
)
*
(
NSEC_PER_SEC
/
HZ
);
set_normalized_timespec
(
&
wall_to_monotonic
,
-
xtime
.
tv_sec
,
-
xtime
.
tv_nsec
);
return
;
return
0
;
}
if
(
tlb_type
==
hypervisor
)
{
xtime
.
tv_sec
=
hypervisor_get_time
();
xtime
.
tv_nsec
=
(
INITIAL_JIFFIES
%
HZ
)
*
(
NSEC_PER_SEC
/
HZ
);
set_normalized_timespec
(
&
wall_to_monotonic
,
-
xtime
.
tv_sec
,
-
xtime
.
tv_nsec
);
return
;
}
/* Check FHC Central then EBUSs then ISA bridges then SBUSs.
* That way we handle the presence of multiple properly.
*
* As a special case, machines with Central must provide the
* timer chip there.
*/
if
(
!
clock_probe_central
()
&&
#ifdef CONFIG_PCI
!
clock_probe_ebus
()
&&
!
clock_probe_isa
()
&&
#endif
#ifdef CONFIG_SBUS
!
clock_probe_sbus
()
#endif
)
{
printk
(
KERN_WARNING
"No clock chip found.
\n
"
);
return
;
}
local_irq_save
(
flags
);
if
(
mstk48t02_regs
!=
NULL
)
{
/* Report a low battery voltage condition. */
if
(
has_low_battery
())
prom_printf
(
"NVRAM: Low battery voltage!
\n
"
);
/* Kick start the clock if it is completely stopped. */
if
(
mostek_read
(
mstk48t02_regs
+
MOSTEK_SEC
)
&
MSTK_STOP
)
kick_start_clock
();
return
0
;
}
set_system_time
();
local_irq_restore
(
flags
);
return
of_register_driver
(
&
clock_driver
,
&
of_bus_type
);
}
/* Must be after subsys_initcall() so that busses are probed. Must
* be before device_initcall() because things like the RTC driver
* need to see the clock registers.
*/
fs_initcall
(
clock_init
);
/* This is gets the master TICK_INT timer going. */
static
unsigned
long
sparc64_init_timers
(
void
)
{
...
...
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