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
bd53d127
Commit
bd53d127
authored
Jun 30, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
parents
12829dcb
bf164c79
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
143 additions
and
21 deletions
+143
-21
drivers/base/base.h
drivers/base/base.h
+1
-0
drivers/base/bus.c
drivers/base/bus.c
+99
-18
drivers/base/core.c
drivers/base/core.c
+1
-1
drivers/base/dd.c
drivers/base/dd.c
+1
-1
drivers/base/driver.c
drivers/base/driver.c
+35
-0
include/linux/device.h
include/linux/device.h
+6
-1
No files found.
drivers/base/base.h
View file @
bd53d127
...
...
@@ -5,6 +5,7 @@ extern int bus_add_driver(struct device_driver *);
extern
void
bus_remove_driver
(
struct
device_driver
*
);
extern
void
driver_detach
(
struct
device_driver
*
drv
);
extern
int
driver_probe_device
(
struct
device_driver
*
,
struct
device
*
);
static
inline
struct
class_device
*
to_class_dev
(
struct
kobject
*
obj
)
{
...
...
drivers/base/bus.c
View file @
bd53d127
...
...
@@ -133,6 +133,58 @@ static struct kobj_type ktype_bus = {
decl_subsys
(
bus
,
&
ktype_bus
,
NULL
);
/* Manually detach a device from it's associated driver. */
static
int
driver_helper
(
struct
device
*
dev
,
void
*
data
)
{
const
char
*
name
=
data
;
if
(
strcmp
(
name
,
dev
->
bus_id
)
==
0
)
return
1
;
return
0
;
}
static
ssize_t
driver_unbind
(
struct
device_driver
*
drv
,
const
char
*
buf
,
size_t
count
)
{
struct
bus_type
*
bus
=
get_bus
(
drv
->
bus
);
struct
device
*
dev
;
int
err
=
-
ENODEV
;
dev
=
bus_find_device
(
bus
,
NULL
,
(
void
*
)
buf
,
driver_helper
);
if
((
dev
)
&&
(
dev
->
driver
==
drv
))
{
device_release_driver
(
dev
);
err
=
count
;
}
return
err
;
}
static
DRIVER_ATTR
(
unbind
,
S_IWUSR
,
NULL
,
driver_unbind
);
/*
* Manually attach a device to a driver.
* Note: the driver must want to bind to the device,
* it is not possible to override the driver's id table.
*/
static
ssize_t
driver_bind
(
struct
device_driver
*
drv
,
const
char
*
buf
,
size_t
count
)
{
struct
bus_type
*
bus
=
get_bus
(
drv
->
bus
);
struct
device
*
dev
;
int
err
=
-
ENODEV
;
dev
=
bus_find_device
(
bus
,
NULL
,
(
void
*
)
buf
,
driver_helper
);
if
((
dev
)
&&
(
dev
->
driver
==
NULL
))
{
down
(
&
dev
->
sem
);
err
=
driver_probe_device
(
drv
,
dev
);
up
(
&
dev
->
sem
);
put_device
(
dev
);
}
return
err
;
}
static
DRIVER_ATTR
(
bind
,
S_IWUSR
,
NULL
,
driver_bind
);
static
struct
device
*
next_device
(
struct
klist_iter
*
i
)
{
struct
klist_node
*
n
=
klist_next
(
i
);
...
...
@@ -177,6 +229,39 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
return
error
;
}
/**
* bus_find_device - device iterator for locating a particular device.
* @bus: bus type
* @start: Device to begin with
* @data: Data to pass to match function
* @match: Callback function to check device
*
* This is similar to the bus_for_each_dev() function above, but it
* returns a reference to a device that is 'found' for later use, as
* determined by the @match callback.
*
* The callback should return 0 if the device doesn't match and non-zero
* if it does. If the callback returns non-zero, this function will
* return to the caller and not iterate over any more devices.
*/
struct
device
*
bus_find_device
(
struct
bus_type
*
bus
,
struct
device
*
start
,
void
*
data
,
int
(
*
match
)(
struct
device
*
,
void
*
))
{
struct
klist_iter
i
;
struct
device
*
dev
;
if
(
!
bus
)
return
NULL
;
klist_iter_init_node
(
&
bus
->
klist_devices
,
&
i
,
(
start
?
&
start
->
knode_bus
:
NULL
));
while
((
dev
=
next_device
(
&
i
)))
if
(
match
(
dev
,
data
)
&&
get_device
(
dev
))
break
;
klist_iter_exit
(
&
i
);
return
dev
;
}
static
struct
device_driver
*
next_driver
(
struct
klist_iter
*
i
)
...
...
@@ -363,6 +448,8 @@ int bus_add_driver(struct device_driver * drv)
module_add_driver
(
drv
->
owner
,
drv
);
driver_add_attrs
(
bus
,
drv
);
driver_create_file
(
drv
,
&
driver_attr_unbind
);
driver_create_file
(
drv
,
&
driver_attr_bind
);
}
return
error
;
}
...
...
@@ -380,6 +467,8 @@ int bus_add_driver(struct device_driver * drv)
void
bus_remove_driver
(
struct
device_driver
*
drv
)
{
if
(
drv
->
bus
)
{
driver_remove_file
(
drv
,
&
driver_attr_bind
);
driver_remove_file
(
drv
,
&
driver_attr_unbind
);
driver_remove_attrs
(
drv
->
bus
,
drv
);
klist_remove
(
&
drv
->
knode_bus
);
pr_debug
(
"bus %s: remove driver %s
\n
"
,
drv
->
bus
->
name
,
drv
->
name
);
...
...
@@ -394,31 +483,22 @@ void bus_remove_driver(struct device_driver * drv)
/* Helper for bus_rescan_devices's iter */
static
int
bus_rescan_devices_helper
(
struct
device
*
dev
,
void
*
data
)
{
int
*
count
=
data
;
if
(
!
dev
->
driver
&&
(
device_attach
(
dev
)
>
0
))
(
*
count
)
++
;
if
(
!
dev
->
driver
)
device_attach
(
dev
);
return
0
;
}
/**
*
bus_rescan_devices - rescan devices on the bus for possible drivers
*
@bus:
the bus to scan.
*
bus_rescan_devices - rescan devices on the bus for possible drivers
*
@bus:
the bus to scan.
*
* This function will look for devices on the bus with no driver
* attached and rescan it against existing drivers to see if it
* matches any. Calls device_attach(). Returns the number of devices
* that were sucessfully bound to a driver.
* This function will look for devices on the bus with no driver
* attached and rescan it against existing drivers to see if it matches
* any by calling device_attach() for the unbound devices.
*/
int
bus_rescan_devices
(
struct
bus_type
*
bus
)
void
bus_rescan_devices
(
struct
bus_type
*
bus
)
{
int
count
=
0
;
bus_for_each_dev
(
bus
,
NULL
,
&
count
,
bus_rescan_devices_helper
);
return
count
;
bus_for_each_dev
(
bus
,
NULL
,
NULL
,
bus_rescan_devices_helper
);
}
...
...
@@ -557,6 +637,7 @@ int __init buses_init(void)
EXPORT_SYMBOL_GPL
(
bus_for_each_dev
);
EXPORT_SYMBOL_GPL
(
bus_find_device
);
EXPORT_SYMBOL_GPL
(
bus_for_each_drv
);
EXPORT_SYMBOL_GPL
(
bus_add_device
);
...
...
drivers/base/core.c
View file @
bd53d127
...
...
@@ -333,7 +333,7 @@ void device_del(struct device * dev)
struct
device
*
parent
=
dev
->
parent
;
if
(
parent
)
klist_
remove
(
&
dev
->
knode_parent
);
klist_
del
(
&
dev
->
knode_parent
);
/* Notify the platform of the removal, in case they
* need to do anything...
...
...
drivers/base/dd.c
View file @
bd53d127
...
...
@@ -65,7 +65,7 @@ void device_bind_driver(struct device * dev)
*
* This function must be called with @dev->sem held.
*/
static
int
driver_probe_device
(
struct
device_driver
*
drv
,
struct
device
*
dev
)
int
driver_probe_device
(
struct
device_driver
*
drv
,
struct
device
*
dev
)
{
int
ret
=
0
;
...
...
drivers/base/driver.c
View file @
bd53d127
...
...
@@ -55,6 +55,41 @@ int driver_for_each_device(struct device_driver * drv, struct device * start,
EXPORT_SYMBOL_GPL
(
driver_for_each_device
);
/**
* driver_find_device - device iterator for locating a particular device.
* @driver: The device's driver
* @start: Device to begin with
* @data: Data to pass to match function
* @match: Callback function to check device
*
* This is similar to the driver_for_each_device() function above, but
* it returns a reference to a device that is 'found' for later use, as
* determined by the @match callback.
*
* The callback should return 0 if the device doesn't match and non-zero
* if it does. If the callback returns non-zero, this function will
* return to the caller and not iterate over any more devices.
*/
struct
device
*
driver_find_device
(
struct
device_driver
*
drv
,
struct
device
*
start
,
void
*
data
,
int
(
*
match
)(
struct
device
*
,
void
*
))
{
struct
klist_iter
i
;
struct
device
*
dev
;
if
(
!
drv
)
return
NULL
;
klist_iter_init_node
(
&
drv
->
klist_devices
,
&
i
,
(
start
?
&
start
->
knode_driver
:
NULL
));
while
((
dev
=
next_device
(
&
i
)))
if
(
match
(
dev
,
data
)
&&
get_device
(
dev
))
break
;
klist_iter_exit
(
&
i
);
return
dev
;
}
EXPORT_SYMBOL_GPL
(
driver_find_device
);
/**
* driver_create_file - create sysfs file for driver.
* @drv: driver.
...
...
include/linux/device.h
View file @
bd53d127
...
...
@@ -69,7 +69,7 @@ struct bus_type {
extern
int
bus_register
(
struct
bus_type
*
bus
);
extern
void
bus_unregister
(
struct
bus_type
*
bus
);
extern
int
bus_rescan_devices
(
struct
bus_type
*
bus
);
extern
void
bus_rescan_devices
(
struct
bus_type
*
bus
);
extern
struct
bus_type
*
get_bus
(
struct
bus_type
*
bus
);
extern
void
put_bus
(
struct
bus_type
*
bus
);
...
...
@@ -80,6 +80,8 @@ extern struct bus_type * find_bus(char * name);
int
bus_for_each_dev
(
struct
bus_type
*
bus
,
struct
device
*
start
,
void
*
data
,
int
(
*
fn
)(
struct
device
*
,
void
*
));
struct
device
*
bus_find_device
(
struct
bus_type
*
bus
,
struct
device
*
start
,
void
*
data
,
int
(
*
match
)(
struct
device
*
,
void
*
));
int
bus_for_each_drv
(
struct
bus_type
*
bus
,
struct
device_driver
*
start
,
void
*
data
,
int
(
*
fn
)(
struct
device_driver
*
,
void
*
));
...
...
@@ -142,6 +144,9 @@ extern void driver_remove_file(struct device_driver *, struct driver_attribute *
extern
int
driver_for_each_device
(
struct
device_driver
*
drv
,
struct
device
*
start
,
void
*
data
,
int
(
*
fn
)(
struct
device
*
,
void
*
));
struct
device
*
driver_find_device
(
struct
device_driver
*
drv
,
struct
device
*
start
,
void
*
data
,
int
(
*
match
)(
struct
device
*
,
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