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
fd531431
Commit
fd531431
authored
Jun 23, 2006
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SPARC]: Port of_device layer and make ebus use it.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
942a6bdd
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
359 additions
and
2 deletions
+359
-2
arch/sparc/kernel/Makefile
arch/sparc/kernel/Makefile
+1
-1
arch/sparc/kernel/ebus.c
arch/sparc/kernel/ebus.c
+21
-0
arch/sparc/kernel/of_device.c
arch/sparc/kernel/of_device.c
+268
-0
include/asm-sparc/ebus.h
include/asm-sparc/ebus.h
+5
-0
include/asm-sparc/of_device.h
include/asm-sparc/of_device.h
+63
-0
include/asm-sparc64/of_device.h
include/asm-sparc64/of_device.h
+1
-1
No files found.
arch/sparc/kernel/Makefile
View file @
fd531431
...
...
@@ -12,7 +12,7 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \
sys_sparc.o sunos_asm.o systbls.o
\
time.o windows.o cpu.o devices.o sclow.o
\
tadpole.o tick14.o ptrace.o sys_solaris.o
\
unaligned.o muldiv.o semaphore.o prom.o
unaligned.o muldiv.o semaphore.o prom.o
of_device.o
obj-$(CONFIG_PCI)
+=
pcic.o
obj-$(CONFIG_SUN4)
+=
sun4setup.o
...
...
arch/sparc/kernel/ebus.c
View file @
fd531431
...
...
@@ -235,6 +235,16 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d
}
}
dev
->
ofdev
.
node
=
dp
;
dev
->
ofdev
.
dev
.
parent
=
&
dev
->
bus
->
ofdev
.
dev
;
dev
->
ofdev
.
dev
.
bus
=
&
ebus_bus_type
;
strcpy
(
dev
->
ofdev
.
dev
.
bus_id
,
dp
->
path_component_name
);
/* Register with core */
if
(
of_device_register
(
&
dev
->
ofdev
)
!=
0
)
printk
(
KERN_DEBUG
"ebus: device registration error for %s!
\n
"
,
dev
->
ofdev
.
dev
.
bus_id
);
if
((
dp
=
dp
->
child
)
!=
NULL
)
{
dev
->
children
=
(
struct
linux_ebus_child
*
)
ebus_alloc
(
sizeof
(
struct
linux_ebus_child
));
...
...
@@ -321,6 +331,17 @@ void __init ebus_init(void)
*
base
++
=
addr
;
}
ebus
->
ofdev
.
node
=
dp
;
ebus
->
ofdev
.
dev
.
parent
=
&
pdev
->
dev
;
ebus
->
ofdev
.
dev
.
bus
=
&
ebus_bus_type
;
strcpy
(
ebus
->
ofdev
.
dev
.
bus_id
,
dp
->
path_component_name
);
/* Register with core */
if
(
of_device_register
(
&
ebus
->
ofdev
)
!=
0
)
printk
(
KERN_DEBUG
"ebus: device registration error for %s!
\n
"
,
ebus
->
ofdev
.
dev
.
bus_id
);
nd
=
dp
->
child
;
if
(
!
nd
)
goto
next_ebus
;
...
...
arch/sparc/kernel/of_device.c
0 → 100644
View file @
fd531431
#include <linux/config.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/slab.h>
#include <asm/errno.h>
#include <asm/of_device.h>
/**
* of_match_device - Tell if an of_device structure has a matching
* of_match structure
* @ids: array of of device match structures to search in
* @dev: the of device structure to match against
*
* Used by a driver to check whether an of_device present in the
* system is in its list of supported devices.
*/
const
struct
of_device_id
*
of_match_device
(
const
struct
of_device_id
*
matches
,
const
struct
of_device
*
dev
)
{
if
(
!
dev
->
node
)
return
NULL
;
while
(
matches
->
name
[
0
]
||
matches
->
type
[
0
]
||
matches
->
compatible
[
0
])
{
int
match
=
1
;
if
(
matches
->
name
[
0
])
match
&=
dev
->
node
->
name
&&
!
strcmp
(
matches
->
name
,
dev
->
node
->
name
);
if
(
matches
->
type
[
0
])
match
&=
dev
->
node
->
type
&&
!
strcmp
(
matches
->
type
,
dev
->
node
->
type
);
if
(
matches
->
compatible
[
0
])
match
&=
of_device_is_compatible
(
dev
->
node
,
matches
->
compatible
);
if
(
match
)
return
matches
;
matches
++
;
}
return
NULL
;
}
static
int
of_platform_bus_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
struct
of_device
*
of_dev
=
to_of_device
(
dev
);
struct
of_platform_driver
*
of_drv
=
to_of_platform_driver
(
drv
);
const
struct
of_device_id
*
matches
=
of_drv
->
match_table
;
if
(
!
matches
)
return
0
;
return
of_match_device
(
matches
,
of_dev
)
!=
NULL
;
}
struct
of_device
*
of_dev_get
(
struct
of_device
*
dev
)
{
struct
device
*
tmp
;
if
(
!
dev
)
return
NULL
;
tmp
=
get_device
(
&
dev
->
dev
);
if
(
tmp
)
return
to_of_device
(
tmp
);
else
return
NULL
;
}
void
of_dev_put
(
struct
of_device
*
dev
)
{
if
(
dev
)
put_device
(
&
dev
->
dev
);
}
static
int
of_device_probe
(
struct
device
*
dev
)
{
int
error
=
-
ENODEV
;
struct
of_platform_driver
*
drv
;
struct
of_device
*
of_dev
;
const
struct
of_device_id
*
match
;
drv
=
to_of_platform_driver
(
dev
->
driver
);
of_dev
=
to_of_device
(
dev
);
if
(
!
drv
->
probe
)
return
error
;
of_dev_get
(
of_dev
);
match
=
of_match_device
(
drv
->
match_table
,
of_dev
);
if
(
match
)
error
=
drv
->
probe
(
of_dev
,
match
);
if
(
error
)
of_dev_put
(
of_dev
);
return
error
;
}
static
int
of_device_remove
(
struct
device
*
dev
)
{
struct
of_device
*
of_dev
=
to_of_device
(
dev
);
struct
of_platform_driver
*
drv
=
to_of_platform_driver
(
dev
->
driver
);
if
(
dev
->
driver
&&
drv
->
remove
)
drv
->
remove
(
of_dev
);
return
0
;
}
static
int
of_device_suspend
(
struct
device
*
dev
,
pm_message_t
state
)
{
struct
of_device
*
of_dev
=
to_of_device
(
dev
);
struct
of_platform_driver
*
drv
=
to_of_platform_driver
(
dev
->
driver
);
int
error
=
0
;
if
(
dev
->
driver
&&
drv
->
suspend
)
error
=
drv
->
suspend
(
of_dev
,
state
);
return
error
;
}
static
int
of_device_resume
(
struct
device
*
dev
)
{
struct
of_device
*
of_dev
=
to_of_device
(
dev
);
struct
of_platform_driver
*
drv
=
to_of_platform_driver
(
dev
->
driver
);
int
error
=
0
;
if
(
dev
->
driver
&&
drv
->
resume
)
error
=
drv
->
resume
(
of_dev
);
return
error
;
}
#ifdef CONFIG_PCI
struct
bus_type
ebus_bus_type
=
{
.
name
=
"ebus"
,
.
match
=
of_platform_bus_match
,
.
probe
=
of_device_probe
,
.
remove
=
of_device_remove
,
.
suspend
=
of_device_suspend
,
.
resume
=
of_device_resume
,
};
#endif
#ifdef CONFIG_SBUS
struct
bus_type
sbus_bus_type
=
{
.
name
=
"sbus"
,
.
match
=
of_platform_bus_match
,
.
probe
=
of_device_probe
,
.
remove
=
of_device_remove
,
.
suspend
=
of_device_suspend
,
.
resume
=
of_device_resume
,
};
#endif
static
int
__init
of_bus_driver_init
(
void
)
{
int
err
=
0
;
#ifdef CONFIG_PCI
if
(
!
err
)
err
=
bus_register
(
&
ebus_bus_type
);
#endif
#ifdef CONFIG_SBUS
if
(
!
err
)
err
=
bus_register
(
&
sbus_bus_type
);
#endif
return
0
;
}
postcore_initcall
(
of_bus_driver_init
);
int
of_register_driver
(
struct
of_platform_driver
*
drv
,
struct
bus_type
*
bus
)
{
/* initialize common driver fields */
drv
->
driver
.
name
=
drv
->
name
;
drv
->
driver
.
bus
=
bus
;
/* register with core */
return
driver_register
(
&
drv
->
driver
);
}
void
of_unregister_driver
(
struct
of_platform_driver
*
drv
)
{
driver_unregister
(
&
drv
->
driver
);
}
static
ssize_t
dev_show_devspec
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
of_device
*
ofdev
;
ofdev
=
to_of_device
(
dev
);
return
sprintf
(
buf
,
"%s"
,
ofdev
->
node
->
full_name
);
}
static
DEVICE_ATTR
(
devspec
,
S_IRUGO
,
dev_show_devspec
,
NULL
);
/**
* of_release_dev - free an of device structure when all users of it are finished.
* @dev: device that's been disconnected
*
* Will be called only by the device core when all users of this of device are
* done.
*/
void
of_release_dev
(
struct
device
*
dev
)
{
struct
of_device
*
ofdev
;
ofdev
=
to_of_device
(
dev
);
kfree
(
ofdev
);
}
int
of_device_register
(
struct
of_device
*
ofdev
)
{
int
rc
;
BUG_ON
(
ofdev
->
node
==
NULL
);
rc
=
device_register
(
&
ofdev
->
dev
);
if
(
rc
)
return
rc
;
device_create_file
(
&
ofdev
->
dev
,
&
dev_attr_devspec
);
return
0
;
}
void
of_device_unregister
(
struct
of_device
*
ofdev
)
{
device_remove_file
(
&
ofdev
->
dev
,
&
dev_attr_devspec
);
device_unregister
(
&
ofdev
->
dev
);
}
struct
of_device
*
of_platform_device_create
(
struct
device_node
*
np
,
const
char
*
bus_id
,
struct
device
*
parent
,
struct
bus_type
*
bus
)
{
struct
of_device
*
dev
;
dev
=
kmalloc
(
sizeof
(
*
dev
),
GFP_KERNEL
);
if
(
!
dev
)
return
NULL
;
memset
(
dev
,
0
,
sizeof
(
*
dev
));
dev
->
dev
.
parent
=
parent
;
dev
->
dev
.
bus
=
bus
;
dev
->
dev
.
release
=
of_release_dev
;
strlcpy
(
dev
->
dev
.
bus_id
,
bus_id
,
BUS_ID_SIZE
);
if
(
of_device_register
(
dev
)
!=
0
)
{
kfree
(
dev
);
return
NULL
;
}
return
dev
;
}
EXPORT_SYMBOL
(
of_match_device
);
EXPORT_SYMBOL
(
of_register_driver
);
EXPORT_SYMBOL
(
of_unregister_driver
);
EXPORT_SYMBOL
(
of_device_register
);
EXPORT_SYMBOL
(
of_device_unregister
);
EXPORT_SYMBOL
(
of_dev_get
);
EXPORT_SYMBOL
(
of_dev_put
);
EXPORT_SYMBOL
(
of_platform_device_create
);
EXPORT_SYMBOL
(
of_release_dev
);
include/asm-sparc/ebus.h
View file @
fd531431
...
...
@@ -14,6 +14,7 @@
#endif
#include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/of_device.h>
struct
linux_ebus_child
{
struct
linux_ebus_child
*
next
;
...
...
@@ -27,6 +28,7 @@ struct linux_ebus_child {
};
struct
linux_ebus_device
{
struct
of_device
ofdev
;
struct
linux_ebus_device
*
next
;
struct
linux_ebus_child
*
children
;
struct
linux_ebus
*
bus
;
...
...
@@ -36,14 +38,17 @@ struct linux_ebus_device {
unsigned
int
irqs
[
PROMINTR_MAX
];
int
num_irqs
;
};
#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
struct
linux_ebus
{
struct
of_device
ofdev
;
struct
linux_ebus
*
next
;
struct
linux_ebus_device
*
devices
;
struct
linux_pbm_info
*
parent
;
struct
pci_dev
*
self
;
struct
device_node
*
prom_node
;
};
#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
struct
linux_ebus_dma
{
unsigned
int
dcsr
;
...
...
include/asm-sparc/of_device.h
0 → 100644
View file @
fd531431
#ifndef _ASM_SPARC_OF_DEVICE_H
#define _ASM_SPARC_OF_DEVICE_H
#ifdef __KERNEL__
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <asm/prom.h>
extern
struct
bus_type
ebus_bus_type
;
extern
struct
bus_type
sbus_bus_type
;
/*
* The of_device is a kind of "base class" that is a superset of
* struct device for use by devices attached to an OF node and
* probed using OF properties.
*/
struct
of_device
{
struct
device_node
*
node
;
/* OF device node */
struct
device
dev
;
/* Generic device interface */
};
#define to_of_device(d) container_of(d, struct of_device, dev)
extern
const
struct
of_device_id
*
of_match_device
(
const
struct
of_device_id
*
matches
,
const
struct
of_device
*
dev
);
extern
struct
of_device
*
of_dev_get
(
struct
of_device
*
dev
);
extern
void
of_dev_put
(
struct
of_device
*
dev
);
/*
* An of_platform_driver driver is attached to a basic of_device on
* the ISA, EBUS, and SBUS busses on sparc64.
*/
struct
of_platform_driver
{
char
*
name
;
struct
of_device_id
*
match_table
;
struct
module
*
owner
;
int
(
*
probe
)(
struct
of_device
*
dev
,
const
struct
of_device_id
*
match
);
int
(
*
remove
)(
struct
of_device
*
dev
);
int
(
*
suspend
)(
struct
of_device
*
dev
,
pm_message_t
state
);
int
(
*
resume
)(
struct
of_device
*
dev
);
int
(
*
shutdown
)(
struct
of_device
*
dev
);
struct
device_driver
driver
;
};
#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver)
extern
int
of_register_driver
(
struct
of_platform_driver
*
drv
,
struct
bus_type
*
bus
);
extern
void
of_unregister_driver
(
struct
of_platform_driver
*
drv
);
extern
int
of_device_register
(
struct
of_device
*
ofdev
);
extern
void
of_device_unregister
(
struct
of_device
*
ofdev
);
extern
struct
of_device
*
of_platform_device_create
(
struct
device_node
*
np
,
const
char
*
bus_id
,
struct
device
*
parent
,
struct
bus_type
*
bus
);
extern
void
of_release_dev
(
struct
device
*
dev
);
#endif
/* __KERNEL__ */
#endif
/* _ASM_SPARC_OF_DEVICE_H */
include/asm-sparc64/of_device.h
View file @
fd531431
...
...
@@ -61,4 +61,4 @@ extern struct of_device *of_platform_device_create(struct device_node *np,
extern
void
of_release_dev
(
struct
device
*
dev
);
#endif
/* __KERNEL__ */
#endif
/* _ASM_
POWERPC
_OF_DEVICE_H */
#endif
/* _ASM_
SPARC64
_OF_DEVICE_H */
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