Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (61 commits)
  Dynamic debug: fix pr_fmt() build error
  Dynamic debug: allow simple quoting of words
  dynamic debug: update docs
  dynamic debug: combine dprintk and dynamic printk
  sysfs: fix some bin_vm_ops errors
  kobject: don't block for each kobject_uevent
  sysfs: only allow one scheduled removal callback per kobj
  Driver core: Fix device_move() vs. dpm list ordering, v2
  Driver core: some cleanup on drivers/base/sys.c
  Driver core: implement uevent suppress in kobject
  vcs: hook sysfs devices into object lifetime instead of "binding"
  driver core: fix passing platform_data
  driver core: move platform_data into platform_device
  sysfs: don't block indefinitely for unmapped files.
  driver core: move knode_bus into private structure
  driver core: move knode_driver into private structure
  driver core: move klist_children into private structure
  driver core: create a private portion of struct device
  driver core: remove polling for driver_probe_done(v5)
  sysfs: reference sysfs_dirent from sysfs inodes
  ...

Fixed conflicts in drivers/sh/maple/maple.c manually
This commit is contained in:
Linus Torvalds
2009-03-26 11:17:04 -07:00
149 changed files with 2664 additions and 1170 deletions

View File

@@ -41,6 +41,13 @@ GPL version 2.
</abstract>
<revhistory>
<revision>
<revnumber>0.8</revnumber>
<date>2008-12-24</date>
<authorinitials>hjk</authorinitials>
<revremark>Added name attributes in mem and portio sysfs directories.
</revremark>
</revision>
<revision>
<revnumber>0.7</revnumber>
<date>2008-12-23</date>
@@ -303,10 +310,17 @@ interested in translating it, please email me
appear if the size of the mapping is not 0.
</para>
<para>
Each <filename>mapX/</filename> directory contains two read-only files
that show start address and size of the memory:
Each <filename>mapX/</filename> directory contains four read-only files
that show attributes of the memory:
</para>
<itemizedlist>
<listitem>
<para>
<filename>name</filename>: A string identifier for this mapping. This
is optional, the string can be empty. Drivers can set this to make it
easier for userspace to find the correct mapping.
</para>
</listitem>
<listitem>
<para>
<filename>addr</filename>: The address of memory that can be mapped.
@@ -366,10 +380,17 @@ offset = N * getpagesize();
<filename>/sys/class/uio/uioX/portio/</filename>.
</para>
<para>
Each <filename>portX/</filename> directory contains three read-only
files that show start, size, and type of the port region:
Each <filename>portX/</filename> directory contains four read-only
files that show name, start, size, and type of the port region:
</para>
<itemizedlist>
<listitem>
<para>
<filename>name</filename>: A string identifier for this port region.
The string is optional and can be empty. Drivers can set it to make it
easier for userspace to find a certain port region.
</para>
</listitem>
<listitem>
<para>
<filename>start</filename>: The first port of this region.

View File

@@ -0,0 +1,240 @@
Introduction
============
This document describes how to use the dynamic debug (ddebug) feature.
Dynamic debug is designed to allow you to dynamically enable/disable kernel
code to obtain additional kernel information. Currently, if
CONFIG_DYNAMIC_DEBUG is set, then all pr_debug()/dev_debug() calls can be
dynamically enabled per-callsite.
Dynamic debug has even more useful features:
* Simple query language allows turning on and off debugging statements by
matching any combination of:
- source filename
- function name
- line number (including ranges of line numbers)
- module name
- format string
* Provides a debugfs control file: <debugfs>/dynamic_debug/control which can be
read to display the complete list of known debug statements, to help guide you
Controlling dynamic debug Behaviour
===============================
The behaviour of pr_debug()/dev_debug()s are controlled via writing to a
control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs
filesystem, in order to make use of this feature. Subsequently, we refer to the
control file as: <debugfs>/dynamic_debug/control. For example, if you want to
enable printing from source file 'svcsock.c', line 1603 you simply do:
nullarbor:~ # echo 'file svcsock.c line 1603 +p' >
<debugfs>/dynamic_debug/control
If you make a mistake with the syntax, the write will fail thus:
nullarbor:~ # echo 'file svcsock.c wtf 1 +p' >
<debugfs>/dynamic_debug/control
-bash: echo: write error: Invalid argument
Viewing Dynamic Debug Behaviour
===========================
You can view the currently configured behaviour of all the debug statements
via:
nullarbor:~ # cat <debugfs>/dynamic_debug/control
# filename:lineno [module]function flags format
/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:323 [svcxprt_rdma]svc_rdma_cleanup - "SVCRDMA Module Removed, deregister RPC RDMA transport\012"
/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:341 [svcxprt_rdma]svc_rdma_init - "\011max_inline : %d\012"
/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:340 [svcxprt_rdma]svc_rdma_init - "\011sq_depth : %d\012"
/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:338 [svcxprt_rdma]svc_rdma_init - "\011max_requests : %d\012"
...
You can also apply standard Unix text manipulation filters to this
data, e.g.
nullarbor:~ # grep -i rdma <debugfs>/dynamic_debug/control | wc -l
62
nullarbor:~ # grep -i tcp <debugfs>/dynamic_debug/control | wc -l
42
Note in particular that the third column shows the enabled behaviour
flags for each debug statement callsite (see below for definitions of the
flags). The default value, no extra behaviour enabled, is "-". So
you can view all the debug statement callsites with any non-default flags:
nullarbor:~ # awk '$3 != "-"' <debugfs>/dynamic_debug/control
# filename:lineno [module]function flags format
/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c:1603 [sunrpc]svc_send p "svc_process: st_sendto returned %d\012"
Command Language Reference
==========================
At the lexical level, a command comprises a sequence of words separated
by whitespace characters. Note that newlines are treated as word
separators and do *not* end a command or allow multiple commands to
be done together. So these are all equivalent:
nullarbor:~ # echo -c 'file svcsock.c line 1603 +p' >
<debugfs>/dynamic_debug/control
nullarbor:~ # echo -c ' file svcsock.c line 1603 +p ' >
<debugfs>/dynamic_debug/control
nullarbor:~ # echo -c 'file svcsock.c\nline 1603 +p' >
<debugfs>/dynamic_debug/control
nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
<debugfs>/dynamic_debug/control
Commands are bounded by a write() system call. If you want to do
multiple commands you need to do a separate "echo" for each, like:
nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;\
> echo 'file svcsock.c line 1563 +p' > /proc/dprintk
or even like:
nullarbor:~ # (
> echo 'file svcsock.c line 1603 +p' ;\
> echo 'file svcsock.c line 1563 +p' ;\
> ) > /proc/dprintk
At the syntactical level, a command comprises a sequence of match
specifications, followed by a flags change specification.
command ::= match-spec* flags-spec
The match-spec's are used to choose a subset of the known dprintk()
callsites to which to apply the flags-spec. Think of them as a query
with implicit ANDs between each pair. Note that an empty list of
match-specs is possible, but is not very useful because it will not
match any debug statement callsites.
A match specification comprises a keyword, which controls the attribute
of the callsite to be compared, and a value to compare against. Possible
keywords are:
match-spec ::= 'func' string |
'file' string |
'module' string |
'format' string |
'line' line-range
line-range ::= lineno |
'-'lineno |
lineno'-' |
lineno'-'lineno
// Note: line-range cannot contain space, e.g.
// "1-30" is valid range but "1 - 30" is not.
lineno ::= unsigned-int
The meanings of each keyword are:
func
The given string is compared against the function name
of each callsite. Example:
func svc_tcp_accept
file
The given string is compared against either the full
pathname or the basename of the source file of each
callsite. Examples:
file svcsock.c
file /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c
module
The given string is compared against the module name
of each callsite. The module name is the string as
seen in "lsmod", i.e. without the directory or the .ko
suffix and with '-' changed to '_'. Examples:
module sunrpc
module nfsd
format
The given string is searched for in the dynamic debug format
string. Note that the string does not need to match the
entire format, only some part. Whitespace and other
special characters can be escaped using C octal character
escape \ooo notation, e.g. the space character is \040.
Alternatively, the string can be enclosed in double quote
characters (") or single quote characters (').
Examples:
format svcrdma: // many of the NFS/RDMA server dprintks
format readahead // some dprintks in the readahead cache
format nfsd:\040SETATTR // one way to match a format with whitespace
format "nfsd: SETATTR" // a neater way to match a format with whitespace
format 'nfsd: SETATTR' // yet another way to match a format with whitespace
line
The given line number or range of line numbers is compared
against the line number of each dprintk() callsite. A single
line number matches the callsite line number exactly. A
range of line numbers matches any callsite between the first
and last line number inclusive. An empty first number means
the first line in the file, an empty line number means the
last number in the file. Examples:
line 1603 // exactly line 1603
line 1600-1605 // the six lines from line 1600 to line 1605
line -1605 // the 1605 lines from line 1 to line 1605
line 1600- // all lines from line 1600 to the end of the file
The flags specification comprises a change operation followed
by one or more flag characters. The change operation is one
of the characters:
-
remove the given flags
+
add the given flags
=
set the flags to the given flags
The flags are:
p
Causes a printk() message to be emitted to dmesg
Note the regexp ^[-+=][scp]+$ matches a flags specification.
Note also that there is no convenient syntax to remove all
the flags at once, you need to use "-psc".
Examples
========
// enable the message at line 1603 of file svcsock.c
nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
<debugfs>/dynamic_debug/control
// enable all the messages in file svcsock.c
nullarbor:~ # echo -n 'file svcsock.c +p' >
<debugfs>/dynamic_debug/control
// enable all the messages in the NFS server module
nullarbor:~ # echo -n 'module nfsd +p' >
<debugfs>/dynamic_debug/control
// enable all 12 messages in the function svc_process()
nullarbor:~ # echo -n 'func svc_process +p' >
<debugfs>/dynamic_debug/control
// disable all 12 messages in the function svc_process()
nullarbor:~ # echo -n 'func svc_process -p' >
<debugfs>/dynamic_debug/control
// enable messages for NFS calls READ, READLINK, READDIR and READDIR+.
nullarbor:~ # echo -n 'format "nfsd: READ" +p' >
<debugfs>/dynamic_debug/control

View File

@@ -1826,11 +1826,6 @@ and is between 256 and 4096 characters. It is defined in the file
autoconfiguration.
Ranges are in pairs (memory base and size).
dynamic_printk Enables pr_debug()/dev_dbg() calls if
CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
These can also be switched on/off via
<debugfs>/dynamic_printk/modules
print-fatal-signals=
[KNL] debug: print fatal signals
print-fatal-signals=1: print segfault info to

View File

@@ -33,8 +33,8 @@
static const struct resource *iodev_get_resource(struct platform_device *, const char *, unsigned int);
static int __init iodev_probe(struct device *);
static int __exit iodev_remove(struct device *);
static int __init iodev_probe(struct platform_device *);
static int __exit iodev_remove(struct platform_device *);
static int iodev_open(struct inode *, struct file *);
static int iodev_release(struct inode *, struct file *);
static ssize_t iodev_read(struct file *, char __user *, size_t s, loff_t *);
@@ -65,13 +65,13 @@ static struct miscdevice miscdev =
.fops = &fops
};
static struct device_driver iodev_driver =
{
.name = (char *) iodev_name,
.bus = &platform_bus_type,
.owner = THIS_MODULE,
static struct platform_driver iodev_driver = {
.driver = {
.name = iodev_name,
.owner = THIS_MODULE,
},
.probe = iodev_probe,
.remove = __exit_p(iodev_remove)
.remove = __devexit_p(iodev_remove),
};
@@ -89,11 +89,10 @@ iodev_get_resource(struct platform_device *pdv, const char *name,
/* No hotplugging on the platform bus - use __init */
static int __init iodev_probe(struct device *dev)
static int __init iodev_probe(struct platform_device *dev)
{
struct platform_device * const pdv = to_platform_device(dev);
const struct resource * const ri =
iodev_get_resource(pdv, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ);
iodev_get_resource(dev, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ);
if (unlikely(!ri))
return -ENXIO;
@@ -104,7 +103,7 @@ static int __init iodev_probe(struct device *dev)
static int __exit iodev_remove(struct device *dev)
static int __exit iodev_remove(struct platform_device *dev)
{
return misc_deregister(&miscdev);
}
@@ -160,14 +159,14 @@ static irqreturn_t iodev_irqhdl(int irq, void *ctxt)
static int __init iodev_init_module(void)
{
return driver_register(&iodev_driver);
return platform_driver_register(&iodev_driver);
}
static void __exit iodev_cleanup_module(void)
{
driver_unregister(&iodev_driver);
platform_driver_unregister(&iodev_driver);
}
module_init(iodev_init_module);

View File

@@ -376,7 +376,7 @@ static int ps3_system_bus_probe(struct device *_dev)
struct ps3_system_bus_driver *drv;
BUG_ON(!dev);
pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
drv = ps3_system_bus_dev_to_system_bus_drv(dev);
BUG_ON(!drv);
@@ -398,7 +398,7 @@ static int ps3_system_bus_remove(struct device *_dev)
struct ps3_system_bus_driver *drv;
BUG_ON(!dev);
pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
drv = ps3_system_bus_dev_to_system_bus_drv(dev);
BUG_ON(!drv);

View File

@@ -977,7 +977,7 @@ static int dock_add(acpi_handle handle)
sizeof(struct dock_station *));
/* we want the dock device to send uevents */
dock_device->dev.uevent_suppress = 0;
dev_set_uevent_suppress(&dock_device->dev, 0);
if (is_dock(handle))
dock_station->flags |= DOCK_IS_DOCK;

View File

@@ -210,7 +210,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
dev->dev.release = amba_device_release;
dev->dev.bus = &amba_bustype;
dev->dev.dma_mask = &dev->dma_mask;
dev->res.name = dev->dev.bus_id;
dev->res.name = dev_name(&dev->dev);
if (!dev->dev.coherent_dma_mask && dev->dma_mask)
dev_warn(&dev->dev, "coherent dma mask is unset\n");
@@ -294,7 +294,7 @@ static int amba_find_match(struct device *dev, void *data)
if (d->parent)
r &= d->parent == dev->parent;
if (d->busid)
r &= strcmp(dev->bus_id, d->busid) == 0;
r &= strcmp(dev_name(dev), d->busid) == 0;
if (r) {
get_device(dev);

View File

@@ -63,6 +63,32 @@ struct class_private {
#define to_class(obj) \
container_of(obj, struct class_private, class_subsys.kobj)
/**
* struct device_private - structure to hold the private to the driver core portions of the device structure.
*
* @klist_children - klist containing all children of this device
* @knode_parent - node in sibling list
* @knode_driver - node in driver list
* @knode_bus - node in bus list
* @device - pointer back to the struct class that this structure is
* associated with.
*
* Nothing outside of the driver core should ever touch these fields.
*/
struct device_private {
struct klist klist_children;
struct klist_node knode_parent;
struct klist_node knode_driver;
struct klist_node knode_bus;
struct device *device;
};
#define to_device_private_parent(obj) \
container_of(obj, struct device_private, knode_parent)
#define to_device_private_driver(obj) \
container_of(obj, struct device_private, knode_driver)
#define to_device_private_bus(obj) \
container_of(obj, struct device_private, knode_bus)
/* initialisation functions */
extern int devices_init(void);
extern int buses_init(void);
@@ -86,6 +112,11 @@ extern void bus_remove_driver(struct device_driver *drv);
extern void driver_detach(struct device_driver *drv);
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
static inline int driver_match_device(struct device_driver *drv,
struct device *dev)
{
return drv->bus->match && drv->bus->match(dev, drv);
}
extern void sysdev_shutdown(void);

View File

@@ -198,7 +198,7 @@ static ssize_t driver_bind(struct device_driver *drv,
int err = -ENODEV;
dev = bus_find_device_by_name(bus, NULL, buf);
if (dev && dev->driver == NULL) {
if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
@@ -253,7 +253,14 @@ static ssize_t store_drivers_probe(struct bus_type *bus,
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
return n ? container_of(n, struct device, knode_bus) : NULL;
struct device *dev = NULL;
struct device_private *dev_prv;
if (n) {
dev_prv = to_device_private_bus(n);
dev = dev_prv->device;
}
return dev;
}
/**
@@ -286,7 +293,7 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start,
return -EINVAL;
klist_iter_init_node(&bus->p->klist_devices, &i,
(start ? &start->knode_bus : NULL));
(start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
@@ -320,7 +327,7 @@ struct device *bus_find_device(struct bus_type *bus,
return NULL;
klist_iter_init_node(&bus->p->klist_devices, &i,
(start ? &start->knode_bus : NULL));
(start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
@@ -507,7 +514,8 @@ void bus_attach_device(struct device *dev)
ret = device_attach(dev);
WARN_ON(ret < 0);
if (ret >= 0)
klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
klist_add_tail(&dev->p->knode_bus,
&bus->p->klist_devices);
}
}
@@ -528,8 +536,8 @@ void bus_remove_device(struct device *dev)
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev));
device_remove_attrs(dev->bus, dev);
if (klist_node_attached(&dev->knode_bus))
klist_del(&dev->knode_bus);
if (klist_node_attached(&dev->p->knode_bus))
klist_del(&dev->p->knode_bus);
pr_debug("bus: '%s': remove device %s\n",
dev->bus->name, dev_name(dev));
@@ -831,14 +839,16 @@ static void bus_remove_attrs(struct bus_type *bus)
static void klist_devices_get(struct klist_node *n)
{
struct device *dev = container_of(n, struct device, knode_bus);
struct device_private *dev_prv = to_device_private_bus(n);
struct device *dev = dev_prv->device;
get_device(dev);
}
static void klist_devices_put(struct klist_node *n)
{
struct device *dev = container_of(n, struct device, knode_bus);
struct device_private *dev_prv = to_device_private_bus(n);
struct device *dev = dev_prv->device;
put_device(dev);
}
@@ -932,6 +942,7 @@ bus_uevent_fail:
kset_unregister(&bus->p->subsys);
kfree(bus->p);
out:
bus->p = NULL;
return retval;
}
EXPORT_SYMBOL_GPL(bus_register);
@@ -953,6 +964,7 @@ void bus_unregister(struct bus_type *bus)
bus_remove_file(bus, &bus_attr_uevent);
kset_unregister(&bus->p->subsys);
kfree(bus->p);
bus->p = NULL;
}
EXPORT_SYMBOL_GPL(bus_unregister);
@@ -993,18 +1005,20 @@ static void device_insertion_sort_klist(struct device *a, struct list_head *list
{
struct list_head *pos;
struct klist_node *n;
struct device_private *dev_prv;
struct device *b;
list_for_each(pos, list) {
n = container_of(pos, struct klist_node, n_node);
b = container_of(n, struct device, knode_bus);
dev_prv = to_device_private_bus(n);
b = dev_prv->device;
if (compare(a, b) <= 0) {
list_move_tail(&a->knode_bus.n_node,
&b->knode_bus.n_node);
list_move_tail(&a->p->knode_bus.n_node,
&b->p->knode_bus.n_node);
return;
}
}
list_move_tail(&a->knode_bus.n_node, list);
list_move_tail(&a->p->knode_bus.n_node, list);
}
void bus_sort_breadthfirst(struct bus_type *bus,
@@ -1014,6 +1028,7 @@ void bus_sort_breadthfirst(struct bus_type *bus,
LIST_HEAD(sorted_devices);
struct list_head *pos, *tmp;
struct klist_node *n;
struct device_private *dev_prv;
struct device *dev;
struct klist *device_klist;
@@ -1022,7 +1037,8 @@ void bus_sort_breadthfirst(struct bus_type *bus,
spin_lock(&device_klist->k_lock);
list_for_each_safe(pos, tmp, &device_klist->k_list) {
n = container_of(pos, struct klist_node, n_node);
dev = container_of(n, struct device, knode_bus);
dev_prv = to_device_private_bus(n);
dev = dev_prv->device;
device_insertion_sort_klist(dev, &sorted_devices, compare);
}
list_splice(&sorted_devices, &device_klist->k_list);

View File

@@ -109,6 +109,7 @@ static struct sysfs_ops dev_sysfs_ops = {
static void device_release(struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
struct device_private *p = dev->p;
if (dev->release)
dev->release(dev);
@@ -120,6 +121,7 @@ static void device_release(struct kobject *kobj)
WARN(1, KERN_ERR "Device '%s' does not have a release() "
"function, it is broken and must be fixed.\n",
dev_name(dev));
kfree(p);
}
static struct kobj_type device_ktype = {
@@ -134,8 +136,6 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
if (ktype == &device_ktype) {
struct device *dev = to_dev(kobj);
if (dev->uevent_suppress)
return 0;
if (dev->bus)
return 1;
if (dev->class)
@@ -507,14 +507,16 @@ EXPORT_SYMBOL_GPL(device_schedule_callback_owner);
static void klist_children_get(struct klist_node *n)
{
struct device *dev = container_of(n, struct device, knode_parent);
struct device_private *p = to_device_private_parent(n);
struct device *dev = p->device;
get_device(dev);
}
static void klist_children_put(struct klist_node *n)
{
struct device *dev = container_of(n, struct device, knode_parent);
struct device_private *p = to_device_private_parent(n);
struct device *dev = p->device;
put_device(dev);
}
@@ -538,8 +540,6 @@ void device_initialize(struct device *dev)
{
dev->kobj.kset = devices_kset;
kobject_init(&dev->kobj, &device_ktype);
klist_init(&dev->klist_children, klist_children_get,
klist_children_put);
INIT_LIST_HEAD(&dev->dma_pools);
init_MUTEX(&dev->sem);
spin_lock_init(&dev->devres_lock);
@@ -777,17 +777,12 @@ static void device_remove_class_symlinks(struct device *dev)
int dev_set_name(struct device *dev, const char *fmt, ...)
{
va_list vargs;
char *s;
int err;
va_start(vargs, fmt);
vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs);
err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
va_end(vargs);
/* ewww... some of these buggers have / in the name... */
while ((s = strchr(dev->bus_id, '/')))
*s = '!';
return 0;
return err;
}
EXPORT_SYMBOL_GPL(dev_set_name);
@@ -864,12 +859,26 @@ int device_add(struct device *dev)
if (!dev)
goto done;
/* Temporarily support init_name if it is set.
* It will override bus_id for now */
if (dev->init_name)
dev_set_name(dev, "%s", dev->init_name);
dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
if (!dev->p) {
error = -ENOMEM;
goto done;
}
dev->p->device = dev;
klist_init(&dev->p->klist_children, klist_children_get,
klist_children_put);
if (!strlen(dev->bus_id))
/*
* for statically allocated devices, which should all be converted
* some day, we need to initialize the name. We prevent reading back
* the name, and force the use of dev_name()
*/
if (dev->init_name) {
dev_set_name(dev, dev->init_name);
dev->init_name = NULL;
}
if (!dev_name(dev))
goto done;
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
@@ -928,7 +937,8 @@ int device_add(struct device *dev)
kobject_uevent(&dev->kobj, KOBJ_ADD);
bus_attach_device(dev);
if (parent)
klist_add_tail(&dev->knode_parent, &parent->klist_children);
klist_add_tail(&dev->p->knode_parent,
&parent->p->klist_children);
if (dev->class) {
mutex_lock(&dev->class->p->class_mutex);
@@ -1042,7 +1052,7 @@ void device_del(struct device *dev)
device_pm_remove(dev);
dpm_sysfs_remove(dev);
if (parent)
klist_del(&dev->knode_parent);
klist_del(&dev->p->knode_parent);
if (MAJOR(dev->devt)) {
device_remove_sys_dev_entry(dev);
device_remove_file(dev, &devt_attr);
@@ -1103,7 +1113,14 @@ void device_unregister(struct device *dev)
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
return n ? container_of(n, struct device, knode_parent) : NULL;
struct device *dev = NULL;
struct device_private *p;
if (n) {
p = to_device_private_parent(n);
dev = p->device;
}
return dev;
}
/**
@@ -1125,7 +1142,7 @@ int device_for_each_child(struct device *parent, void *data,
struct device *child;
int error = 0;
klist_iter_init(&parent->klist_children, &i);
klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)) && !error)
error = fn(child, data);
klist_iter_exit(&i);
@@ -1156,7 +1173,7 @@ struct device *device_find_child(struct device *parent, void *data,
if (!parent)
return NULL;
klist_iter_init(&parent->klist_children, &i);
klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)))
if (match(child, data) && get_device(child))
break;
@@ -1348,7 +1365,10 @@ struct device *device_create_vargs(struct class *class, struct device *parent,
dev->release = device_create_release;
dev_set_drvdata(dev, drvdata);
vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);
retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
if (retval)
goto error;
retval = device_register(dev);
if (retval)
goto error;
@@ -1452,19 +1472,15 @@ int device_rename(struct device *dev, char *new_name)
old_class_name = make_class_name(dev->class->name, &dev->kobj);
#endif
old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
if (!old_device_name) {
error = -ENOMEM;
goto out;
}
strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
error = kobject_rename(&dev->kobj, new_name);
if (error) {
strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
if (error)
goto out;
}
#ifdef CONFIG_SYSFS_DEPRECATED
if (old_class_name) {
@@ -1545,8 +1561,10 @@ out:
* device_move - moves a device to a new parent
* @dev: the pointer to the struct device to be moved
* @new_parent: the new parent of the device (can by NULL)
* @dpm_order: how to reorder the dpm_list
*/
int device_move(struct device *dev, struct device *new_parent)
int device_move(struct device *dev, struct device *new_parent,
enum dpm_order dpm_order)
{
int error;
struct device *old_parent;
@@ -1556,6 +1574,7 @@ int device_move(struct device *dev, struct device *new_parent)
if (!dev)
return -EINVAL;
device_pm_lock();
new_parent = get_device(new_parent);
new_parent_kobj = get_device_parent(dev, new_parent);
@@ -1570,9 +1589,10 @@ int device_move(struct device *dev, struct device *new_parent)
old_parent = dev->parent;
dev->parent = new_parent;
if (old_parent)
klist_remove(&dev->knode_parent);
klist_remove(&dev->p->knode_parent);
if (new_parent) {
klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
klist_add_tail(&dev->p->knode_parent,
&new_parent->p->klist_children);
set_dev_node(dev, dev_to_node(new_parent));
}
@@ -1584,11 +1604,11 @@ int device_move(struct device *dev, struct device *new_parent)
device_move_class_links(dev, new_parent, old_parent);
if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
if (new_parent)
klist_remove(&dev->knode_parent);
klist_remove(&dev->p->knode_parent);
dev->parent = old_parent;
if (old_parent) {
klist_add_tail(&dev->knode_parent,
&old_parent->klist_children);
klist_add_tail(&dev->p->knode_parent,
&old_parent->p->klist_children);
set_dev_node(dev, dev_to_node(old_parent));
}
}
@@ -1596,9 +1616,23 @@ int device_move(struct device *dev, struct device *new_parent)
put_device(new_parent);
goto out;
}
switch (dpm_order) {
case DPM_ORDER_NONE:
break;
case DPM_ORDER_DEV_AFTER_PARENT:
device_pm_move_after(dev, new_parent);
break;
case DPM_ORDER_PARENT_BEFORE_DEV:
device_pm_move_before(new_parent, dev);
break;
case DPM_ORDER_DEV_LAST:
device_pm_move_last(dev);
break;
}
out_put:
put_device(old_parent);
out:
device_pm_unlock();
put_device(dev);
return error;
}

View File

@@ -30,7 +30,7 @@
static void driver_bound(struct device *dev)
{
if (klist_node_attached(&dev->knode_driver)) {
if (klist_node_attached(&dev->p->knode_driver)) {
printk(KERN_WARNING "%s: device %s already bound\n",
__func__, kobject_name(&dev->kobj));
return;
@@ -43,7 +43,7 @@ static void driver_bound(struct device *dev)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_BOUND_DRIVER, dev);
klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices);
klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
}
static int driver_sysfs_add(struct device *dev)
@@ -172,16 +172,12 @@ int driver_probe_done(void)
/**
* wait_for_device_probe
* Wait for device probing to be completed.
*
* Note: this function polls at 100 msec intervals.
*/
int wait_for_device_probe(void)
void wait_for_device_probe(void)
{
/* wait for the known devices to complete their probing */
while (driver_probe_done() != 0)
msleep(100);
wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
async_synchronize_full();
return 0;
}
/**
@@ -189,14 +185,8 @@ int wait_for_device_probe(void)
* @drv: driver to bind a device to
* @dev: device to try to bind to the driver
*
* First, we call the bus's match function, if one present, which should
* compare the device IDs the driver supports with the device IDs of the
* device. Note we don't do this ourselves because we don't know the
* format of the ID structures, nor what is to be considered a match and
* what is not.
*
* This function returns 1 if a match is found, -ENODEV if the device is
* not registered, and 0 otherwise.
* This function returns -ENODEV if the device is not registered,
* 1 if the device is bound sucessfully and 0 otherwise.
*
* This function must be called with @dev->sem held. When called for a
* USB interface, @dev->parent->sem must be held as well.
@@ -207,21 +197,22 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
if (!device_is_registered(dev))
return -ENODEV;
if (drv->bus->match && !drv->bus->match(dev, drv))
goto done;
pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
drv->bus->name, __func__, dev_name(dev), drv->name);
ret = really_probe(dev, drv);
done:
return ret;
}
static int __device_attach(struct device_driver *drv, void *data)
{
struct device *dev = data;
if (!driver_match_device(drv, dev))
return 0;
return driver_probe_device(drv, dev);
}
@@ -274,7 +265,7 @@ static int __driver_attach(struct device *dev, void *data)
* is an error.
*/
if (drv->bus->match && !drv->bus->match(dev, drv))
if (!driver_match_device(drv, dev))
return 0;
if (dev->parent) /* Needed for USB */
@@ -327,7 +318,7 @@ static void __device_release_driver(struct device *dev)
drv->remove(dev);
devres_release_all(dev);
dev->driver = NULL;
klist_remove(&dev->knode_driver);
klist_remove(&dev->p->knode_driver);
}
}
@@ -357,6 +348,7 @@ EXPORT_SYMBOL_GPL(device_release_driver);
*/
void driver_detach(struct device_driver *drv)
{
struct device_private *dev_prv;
struct device *dev;
for (;;) {
@@ -365,8 +357,10 @@ void driver_detach(struct device_driver *drv)
spin_unlock(&drv->p->klist_devices.k_lock);
break;
}
dev = list_entry(drv->p->klist_devices.k_list.prev,
struct device, knode_driver.n_node);
dev_prv = list_entry(drv->p->klist_devices.k_list.prev,
struct device_private,
knode_driver.n_node);
dev = dev_prv->device;
get_device(dev);
spin_unlock(&drv->p->klist_devices.k_lock);

View File

@@ -19,7 +19,14 @@
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
return n ? container_of(n, struct device, knode_driver) : NULL;
struct device *dev = NULL;
struct device_private *dev_prv;
if (n) {
dev_prv = to_device_private_driver(n);
dev = dev_prv->device;
}
return dev;
}
/**
@@ -42,7 +49,7 @@ int driver_for_each_device(struct device_driver *drv, struct device *start,
return -EINVAL;
klist_iter_init_node(&drv->p->klist_devices, &i,
start ? &start->knode_driver : NULL);
start ? &start->p->knode_driver : NULL);
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
@@ -76,7 +83,7 @@ struct device *driver_find_device(struct device_driver *drv,
return NULL;
klist_iter_init_node(&drv->p->klist_devices, &i,
(start ? &start->knode_driver : NULL));
(start ? &start->p->knode_driver : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
@@ -216,6 +223,8 @@ int driver_register(struct device_driver *drv)
int ret;
struct device_driver *other;
BUG_ON(!drv->bus->p);
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown))

View File

@@ -319,7 +319,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
f_dev->parent = device;
f_dev->class = &firmware_class;
dev_set_drvdata(f_dev, fw_priv);
f_dev->uevent_suppress = 1;
dev_set_uevent_suppress(f_dev, 1);
retval = device_register(f_dev);
if (retval) {
dev_err(device, "%s: device_register failed\n", __func__);
@@ -366,7 +366,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
}
if (uevent)
f_dev->uevent_suppress = 0;
dev_set_uevent_suppress(f_dev, 0);
*dev_p = f_dev;
goto out;

View File

@@ -217,6 +217,7 @@ int platform_device_add_data(struct platform_device *pdev, const void *data,
if (d) {
memcpy(d, data, size);
pdev->dev.platform_data = d;
pdev->platform_data = d;
}
return d ? 0 : -ENOMEM;
}
@@ -246,6 +247,21 @@ int platform_device_add(struct platform_device *pdev)
else
dev_set_name(&pdev->dev, pdev->name);
/* We will remove platform_data field from struct device
* if all platform devices pass its platform specific data
* from platform_device. The conversion is going to be a
* long time, so we allow the two cases coexist to make
* this kind of fix more easily*/
if (pdev->platform_data && pdev->dev.platform_data) {
printk(KERN_ERR
"%s: use which platform_data?\n",
dev_name(&pdev->dev));
} else if (pdev->platform_data) {
pdev->dev.platform_data = pdev->platform_data;
} else if (pdev->dev.platform_data) {
pdev->platform_data = pdev->dev.platform_data;
}
for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];
@@ -584,10 +600,25 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct platform_device *pdev = to_platform_device(dev);
add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
(pdev->id_entry) ? pdev->id_entry->name : pdev->name);
return 0;
}
static const struct platform_device_id *platform_match_id(
struct platform_device_id *id,
struct platform_device *pdev)
{
while (id->name[0]) {
if (strcmp(pdev->name, id->name) == 0) {
pdev->id_entry = id;
return id;
}
id++;
}
return NULL;
}
/**
* platform_match - bind platform device to platform driver.
* @dev: device.
@@ -603,9 +634,14 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
*/
static int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev;
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
pdev = container_of(dev, struct platform_device, dev);
/* match against the id table first */
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}
@@ -623,26 +659,24 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg)
{
struct platform_driver *drv = to_platform_driver(dev->driver);
struct platform_device *pdev;
struct platform_driver *pdrv = to_platform_driver(dev->driver);
struct platform_device *pdev = to_platform_device(dev);
int ret = 0;
pdev = container_of(dev, struct platform_device, dev);
if (dev->driver && drv->suspend_late)
ret = drv->suspend_late(pdev, mesg);
if (dev->driver && pdrv->suspend_late)
ret = pdrv->suspend_late(pdev, mesg);
return ret;
}
static int platform_legacy_resume_early(struct device *dev)
{
struct platform_driver *drv = to_platform_driver(dev->driver);
struct platform_device *pdev;
struct platform_driver *pdrv = to_platform_driver(dev->driver);
struct platform_device *pdev = to_platform_device(dev);
int ret = 0;
pdev = container_of(dev, struct platform_device, dev);
if (dev->driver && drv->resume_early)
ret = drv->resume_early(pdev);
if (dev->driver && pdrv->resume_early)
ret = pdrv->resume_early(pdev);
return ret;
}

View File

@@ -106,6 +106,50 @@ void device_pm_remove(struct device *dev)
mutex_unlock(&dpm_list_mtx);
}
/**
* device_pm_move_before - move device in dpm_list
* @deva: Device to move in dpm_list
* @devb: Device @deva should come before
*/
void device_pm_move_before(struct device *deva, struct device *devb)
{
pr_debug("PM: Moving %s:%s before %s:%s\n",
deva->bus ? deva->bus->name : "No Bus",
kobject_name(&deva->kobj),
devb->bus ? devb->bus->name : "No Bus",
kobject_name(&devb->kobj));
/* Delete deva from dpm_list and reinsert before devb. */
list_move_tail(&deva->power.entry, &devb->power.entry);
}
/**
* device_pm_move_after - move device in dpm_list
* @deva: Device to move in dpm_list
* @devb: Device @deva should come after
*/
void device_pm_move_after(struct device *deva, struct device *devb)
{
pr_debug("PM: Moving %s:%s after %s:%s\n",
deva->bus ? deva->bus->name : "No Bus",
kobject_name(&deva->kobj),
devb->bus ? devb->bus->name : "No Bus",
kobject_name(&devb->kobj));
/* Delete deva from dpm_list and reinsert after devb. */
list_move(&deva->power.entry, &devb->power.entry);
}
/**
* device_pm_move_last - move device to end of dpm_list
* @dev: Device to move in dpm_list
*/
void device_pm_move_last(struct device *dev)
{
pr_debug("PM: Moving %s:%s to end of list\n",
dev->bus ? dev->bus->name : "No Bus",
kobject_name(&dev->kobj));
list_move_tail(&dev->power.entry, &dpm_list);
}
/**
* pm_op - execute the PM operation appropiate for given PM event
* @dev: Device.

View File

@@ -18,11 +18,19 @@ static inline struct device *to_device(struct list_head *entry)
extern void device_pm_add(struct device *);
extern void device_pm_remove(struct device *);
extern void device_pm_move_before(struct device *, struct device *);
extern void device_pm_move_after(struct device *, struct device *);
extern void device_pm_move_last(struct device *);
#else /* CONFIG_PM_SLEEP */
static inline void device_pm_add(struct device *dev) {}
static inline void device_pm_remove(struct device *dev) {}
static inline void device_pm_move_before(struct device *deva,
struct device *devb) {}
static inline void device_pm_move_after(struct device *deva,
struct device *devb) {}
static inline void device_pm_move_last(struct device *dev) {}
#endif

View File

@@ -30,10 +30,10 @@
static ssize_t
sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer)
{
struct sys_device * sysdev = to_sysdev(kobj);
struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
struct sys_device *sysdev = to_sysdev(kobj);
struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->show)
return sysdev_attr->show(sysdev, sysdev_attr, buffer);
@@ -42,11 +42,11 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
static ssize_t
sysdev_store(struct kobject * kobj, struct attribute * attr,
const char * buffer, size_t count)
sysdev_store(struct kobject *kobj, struct attribute *attr,
const char *buffer, size_t count)
{
struct sys_device * sysdev = to_sysdev(kobj);
struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
struct sys_device *sysdev = to_sysdev(kobj);
struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->store)
return sysdev_attr->store(sysdev, sysdev_attr, buffer, count);
@@ -63,13 +63,13 @@ static struct kobj_type ktype_sysdev = {
};
int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a)
int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a)
{
return sysfs_create_file(&s->kobj, &a->attr);
}
void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a)
{
sysfs_remove_file(&s->kobj, &a->attr);
}
@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(sysdev_remove_file);
static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
char *buffer)
{
struct sysdev_class * class = to_sysdev_class(kobj);
struct sysdev_class *class = to_sysdev_class(kobj);
struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
if (class_attr->show)
@@ -95,8 +95,8 @@ static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
const char *buffer, size_t count)
{
struct sysdev_class * class = to_sysdev_class(kobj);
struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr);
struct sysdev_class *class = to_sysdev_class(kobj);
struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
if (class_attr->store)
return class_attr->store(class, buffer, count);
@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
static struct kset *system_kset;
int sysdev_class_register(struct sysdev_class * cls)
int sysdev_class_register(struct sysdev_class *cls)
{
pr_debug("Registering sysdev class '%s'\n", cls->name);
@@ -141,7 +141,7 @@ int sysdev_class_register(struct sysdev_class * cls)
return kset_register(&cls->kset);
}
void sysdev_class_unregister(struct sysdev_class * cls)
void sysdev_class_unregister(struct sysdev_class *cls)
{
pr_debug("Unregistering sysdev class '%s'\n",
kobject_name(&cls->kset.kobj));
@@ -203,8 +203,8 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
* @cls: Class driver belongs to.
* @drv: Driver.
*/
void sysdev_driver_unregister(struct sysdev_class * cls,
struct sysdev_driver * drv)
void sysdev_driver_unregister(struct sysdev_class *cls,
struct sysdev_driver *drv)
{
mutex_lock(&sysdev_drivers_lock);
list_del_init(&drv->entry);
@@ -229,10 +229,10 @@ EXPORT_SYMBOL_GPL(sysdev_driver_unregister);
* @sysdev: device in question
*
*/
int sysdev_register(struct sys_device * sysdev)
int sysdev_register(struct sys_device *sysdev)
{
int error;
struct sysdev_class * cls = sysdev->cls;
struct sysdev_class *cls = sysdev->cls;
if (!cls)
return -EINVAL;
@@ -252,7 +252,7 @@ int sysdev_register(struct sys_device * sysdev)
sysdev->id);
if (!error) {
struct sysdev_driver * drv;
struct sysdev_driver *drv;
pr_debug("Registering sys device '%s'\n",
kobject_name(&sysdev->kobj));
@@ -274,9 +274,9 @@ int sysdev_register(struct sys_device * sysdev)
return error;
}
void sysdev_unregister(struct sys_device * sysdev)
void sysdev_unregister(struct sys_device *sysdev)
{
struct sysdev_driver * drv;
struct sysdev_driver *drv;
mutex_lock(&sysdev_drivers_lock);
list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
@@ -305,19 +305,19 @@ void sysdev_unregister(struct sys_device * sysdev)
*/
void sysdev_shutdown(void)
{
struct sysdev_class * cls;
struct sysdev_class *cls;
pr_debug("Shutting Down System Devices\n");
mutex_lock(&sysdev_drivers_lock);
list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
struct sys_device * sysdev;
struct sys_device *sysdev;
pr_debug("Shutting down type '%s':\n",
kobject_name(&cls->kset.kobj));
list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
struct sysdev_driver * drv;
struct sysdev_driver *drv;
pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* Call auxillary drivers first */
@@ -364,7 +364,7 @@ static void __sysdev_resume(struct sys_device *dev)
*/
int sysdev_suspend(pm_message_t state)
{
struct sysdev_class * cls;
struct sysdev_class *cls;
struct sys_device *sysdev, *err_dev;
struct sysdev_driver *drv, *err_drv;
int ret;
@@ -442,12 +442,12 @@ EXPORT_SYMBOL_GPL(sysdev_suspend);
*/
int sysdev_resume(void)
{
struct sysdev_class * cls;
struct sysdev_class *cls;
pr_debug("Resuming System Devices\n");
list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) {
struct sys_device * sysdev;
struct sys_device *sysdev;
pr_debug("Resuming type '%s':\n",
kobject_name(&cls->kset.kobj));

View File

@@ -4135,10 +4135,9 @@ static int have_no_fdc = -ENODEV;
static ssize_t floppy_cmos_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct platform_device *p;
struct platform_device *p = to_platform_device(dev);
int drive;
p = container_of(dev, struct platform_device,dev);
drive = p->id;
return sprintf(buf, "%X\n", UDP->cmos);
}

View File

@@ -168,12 +168,22 @@ static void atml_plat_remove(void)
}
}
static struct device_driver atml_drv = {
.name = "tpm_atmel",
.bus = &platform_bus_type,
.owner = THIS_MODULE,
.suspend = tpm_pm_suspend,
.resume = tpm_pm_resume,
static int tpm_atml_suspend(struct platform_device *dev, pm_message_t msg)
{
return tpm_pm_suspend(&dev->dev, msg);
}
static int tpm_atml_resume(struct platform_device *dev)
{
return tpm_pm_resume(&dev->dev);
}
static struct platform_driver atml_drv = {
.driver = {
.name = "tpm_atmel",
.owner = THIS_MODULE,
},
.suspend = tpm_atml_suspend,
.resume = tpm_atml_resume,
};
static int __init init_atmel(void)
@@ -184,7 +194,7 @@ static int __init init_atmel(void)
unsigned long base;
struct tpm_chip *chip;
rc = driver_register(&atml_drv);
rc = platform_driver_register(&atml_drv);
if (rc)
return rc;
@@ -223,13 +233,13 @@ err_rel_reg:
atmel_release_region(base,
region_size);
err_unreg_drv:
driver_unregister(&atml_drv);
platform_driver_unregister(&atml_drv);
return rc;
}
static void __exit cleanup_atmel(void)
{
driver_unregister(&atml_drv);
platform_driver_unregister(&atml_drv);
atml_plat_remove();
}

View File

@@ -654,12 +654,22 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
static struct device_driver tis_drv = {
.name = "tpm_tis",
.bus = &platform_bus_type,
.owner = THIS_MODULE,
.suspend = tpm_pm_suspend,
.resume = tpm_pm_resume,
static int tpm_tis_suspend(struct platform_device *dev, pm_message_t msg)
{
return tpm_pm_suspend(&dev->dev, msg);
}
static int tpm_tis_resume(struct platform_device *dev)
{
return tpm_pm_resume(&dev->dev);
}
static struct platform_driver tis_drv = {
.driver = {
.name = "tpm_tis",
.owner = THIS_MODULE,
},
.suspend = tpm_tis_suspend,
.resume = tpm_tis_resume,
};
static struct platform_device *pdev;
@@ -672,14 +682,14 @@ static int __init init_tis(void)
int rc;
if (force) {
rc = driver_register(&tis_drv);
rc = platform_driver_register(&tis_drv);
if (rc < 0)
return rc;
if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
return PTR_ERR(pdev);
if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
platform_device_unregister(pdev);
driver_unregister(&tis_drv);
platform_driver_unregister(&tis_drv);
}
return rc;
}
@@ -711,7 +721,7 @@ static void __exit cleanup_tis(void)
if (force) {
platform_device_unregister(pdev);
driver_unregister(&tis_drv);
platform_driver_unregister(&tis_drv);
} else
pnp_unregister_driver(&tis_pnp_driver);
}

Some files were not shown because too many files have changed in this diff Show More