mirror of https://gitee.com/openkylin/linux.git
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6: firmware: remove orphaned Email kobject: use the proper printk level for kobject error Driver core: kill unused code Driver core: keep PHYSDEV for old struct class_device update Documentation/driver-model/platform.txt
This commit is contained in:
commit
837525e344
|
@ -96,6 +96,46 @@ System setup also associates those clocks with the device, so that that
|
||||||
calls to clk_get(&pdev->dev, clock_name) return them as needed.
|
calls to clk_get(&pdev->dev, clock_name) return them as needed.
|
||||||
|
|
||||||
|
|
||||||
|
Legacy Drivers: Device Probing
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Some drivers are not fully converted to the driver model, because they take
|
||||||
|
on a non-driver role: the driver registers its platform device, rather than
|
||||||
|
leaving that for system infrastructure. Such drivers can't be hotplugged
|
||||||
|
or coldplugged, since those mechanisms require device creation to be in a
|
||||||
|
different system component than the driver.
|
||||||
|
|
||||||
|
The only "good" reason for this is to handle older system designs which, like
|
||||||
|
original IBM PCs, rely on error-prone "probe-the-hardware" models for hardware
|
||||||
|
configuration. Newer systems have largely abandoned that model, in favor of
|
||||||
|
bus-level support for dynamic configuration (PCI, USB), or device tables
|
||||||
|
provided by the boot firmware (e.g. PNPACPI on x86). There are too many
|
||||||
|
conflicting options about what might be where, and even educated guesses by
|
||||||
|
an operating system will be wrong often enough to make trouble.
|
||||||
|
|
||||||
|
This style of driver is discouraged. If you're updating such a driver,
|
||||||
|
please try to move the device enumeration to a more appropriate location,
|
||||||
|
outside the driver. This will usually be cleanup, since such drivers
|
||||||
|
tend to already have "normal" modes, such as ones using device nodes that
|
||||||
|
were created by PNP or by platform device setup.
|
||||||
|
|
||||||
|
None the less, there are some APIs to support such legacy drivers. Avoid
|
||||||
|
using these calls except with such hotplug-deficient drivers.
|
||||||
|
|
||||||
|
struct platform_device *platform_device_alloc(
|
||||||
|
char *name, unsigned id);
|
||||||
|
|
||||||
|
You can use platform_device_alloc() to dynamically allocate a device, which
|
||||||
|
you will then initialize with resources and platform_device_register().
|
||||||
|
A better solution is usually:
|
||||||
|
|
||||||
|
struct platform_device *platform_device_register_simple(
|
||||||
|
char *name, unsigned id,
|
||||||
|
struct resource *res, unsigned nres);
|
||||||
|
|
||||||
|
You can use platform_device_register_simple() as a one-step call to allocate
|
||||||
|
and register a device.
|
||||||
|
|
||||||
|
|
||||||
Device Naming and Driver Binding
|
Device Naming and Driver Binding
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The platform_device.dev.bus_id is the canonical name for the devices.
|
The platform_device.dev.bus_id is the canonical name for the devices.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
request_firmware() hotplug interface:
|
request_firmware() hotplug interface:
|
||||||
------------------------------------
|
------------------------------------
|
||||||
Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
|
Copyright (C) 2003 Manuel Estrada Sainz
|
||||||
|
|
||||||
Why:
|
Why:
|
||||||
---
|
---
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* firmware_sample_driver.c -
|
* firmware_sample_driver.c -
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
|
* Copyright (c) 2003 Manuel Estrada Sainz
|
||||||
*
|
*
|
||||||
* Sample code on how to use request_firmware() from drivers.
|
* Sample code on how to use request_firmware() from drivers.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* firmware_sample_firmware_class.c -
|
* firmware_sample_firmware_class.c -
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
|
* Copyright (c) 2003 Manuel Estrada Sainz
|
||||||
*
|
*
|
||||||
* NOTE: This is just a probe of concept, if you think that your driver would
|
* NOTE: This is just a probe of concept, if you think that your driver would
|
||||||
* be well served by this mechanism please contact me first.
|
* be well served by this mechanism please contact me first.
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
|
MODULE_AUTHOR("Manuel Estrada Sainz");
|
||||||
MODULE_DESCRIPTION("Hackish sample for using firmware class directly");
|
MODULE_DESCRIPTION("Hackish sample for using firmware class directly");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
|
|
@ -369,36 +369,6 @@ char *make_class_name(const char *name, struct kobject *kobj)
|
||||||
return class_name;
|
return class_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int deprecated_class_uevent(char **envp, int num_envp, int *cur_index,
|
|
||||||
char *buffer, int buffer_size,
|
|
||||||
int *cur_len,
|
|
||||||
struct class_device *class_dev)
|
|
||||||
{
|
|
||||||
struct device *dev = class_dev->dev;
|
|
||||||
char *path;
|
|
||||||
|
|
||||||
if (!dev)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* add device, backing this class device (deprecated) */
|
|
||||||
path = kobject_get_path(&dev->kobj, GFP_KERNEL);
|
|
||||||
|
|
||||||
add_uevent_var(envp, num_envp, cur_index, buffer, buffer_size,
|
|
||||||
cur_len, "PHYSDEVPATH=%s", path);
|
|
||||||
kfree(path);
|
|
||||||
|
|
||||||
if (dev->bus)
|
|
||||||
add_uevent_var(envp, num_envp, cur_index,
|
|
||||||
buffer, buffer_size, cur_len,
|
|
||||||
"PHYSDEVBUS=%s", dev->bus->name);
|
|
||||||
|
|
||||||
if (dev->driver)
|
|
||||||
add_uevent_var(envp, num_envp, cur_index,
|
|
||||||
buffer, buffer_size, cur_len,
|
|
||||||
"PHYSDEVDRIVER=%s", dev->driver->name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int make_deprecated_class_device_links(struct class_device *class_dev)
|
static int make_deprecated_class_device_links(struct class_device *class_dev)
|
||||||
{
|
{
|
||||||
char *class_name;
|
char *class_name;
|
||||||
|
@ -430,11 +400,6 @@ static void remove_deprecated_class_device_links(struct class_device *class_dev)
|
||||||
kfree(class_name);
|
kfree(class_name);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline int deprecated_class_uevent(char **envp, int num_envp,
|
|
||||||
int *cur_index, char *buffer,
|
|
||||||
int buffer_size, int *cur_len,
|
|
||||||
struct class_device *class_dev)
|
|
||||||
{ return 0; }
|
|
||||||
static inline int make_deprecated_class_device_links(struct class_device *cd)
|
static inline int make_deprecated_class_device_links(struct class_device *cd)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
static void remove_deprecated_class_device_links(struct class_device *cd)
|
static void remove_deprecated_class_device_links(struct class_device *cd)
|
||||||
|
@ -445,15 +410,13 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
|
||||||
int num_envp, char *buffer, int buffer_size)
|
int num_envp, char *buffer, int buffer_size)
|
||||||
{
|
{
|
||||||
struct class_device *class_dev = to_class_dev(kobj);
|
struct class_device *class_dev = to_class_dev(kobj);
|
||||||
|
struct device *dev = class_dev->dev;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
|
pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
|
||||||
|
|
||||||
deprecated_class_uevent(envp, num_envp, &i, buffer, buffer_size,
|
|
||||||
&length, class_dev);
|
|
||||||
|
|
||||||
if (MAJOR(class_dev->devt)) {
|
if (MAJOR(class_dev->devt)) {
|
||||||
add_uevent_var(envp, num_envp, &i,
|
add_uevent_var(envp, num_envp, &i,
|
||||||
buffer, buffer_size, &length,
|
buffer, buffer_size, &length,
|
||||||
|
@ -464,6 +427,26 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
|
||||||
"MINOR=%u", MINOR(class_dev->devt));
|
"MINOR=%u", MINOR(class_dev->devt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev) {
|
||||||
|
const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
|
||||||
|
if (path) {
|
||||||
|
add_uevent_var(envp, num_envp, &i,
|
||||||
|
buffer, buffer_size, &length,
|
||||||
|
"PHYSDEVPATH=%s", path);
|
||||||
|
kfree(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->bus)
|
||||||
|
add_uevent_var(envp, num_envp, &i,
|
||||||
|
buffer, buffer_size, &length,
|
||||||
|
"PHYSDEVBUS=%s", dev->bus->name);
|
||||||
|
|
||||||
|
if (dev->driver)
|
||||||
|
add_uevent_var(envp, num_envp, &i,
|
||||||
|
buffer, buffer_size, &length,
|
||||||
|
"PHYSDEVDRIVER=%s", dev->driver->name);
|
||||||
|
}
|
||||||
|
|
||||||
/* terminate, set to next free slot, shrink available space */
|
/* terminate, set to next free slot, shrink available space */
|
||||||
envp[i] = NULL;
|
envp[i] = NULL;
|
||||||
envp = &envp[i];
|
envp = &envp[i];
|
||||||
|
|
|
@ -180,10 +180,12 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
|
||||||
const char *path;
|
const char *path;
|
||||||
|
|
||||||
path = kobject_get_path(&parent->kobj, GFP_KERNEL);
|
path = kobject_get_path(&parent->kobj, GFP_KERNEL);
|
||||||
|
if (path) {
|
||||||
add_uevent_var(envp, num_envp, &i,
|
add_uevent_var(envp, num_envp, &i,
|
||||||
buffer, buffer_size, &length,
|
buffer, buffer_size, &length,
|
||||||
"PHYSDEVPATH=%s", path);
|
"PHYSDEVPATH=%s", path);
|
||||||
kfree(path);
|
kfree(path);
|
||||||
|
}
|
||||||
|
|
||||||
add_uevent_var(envp, num_envp, &i,
|
add_uevent_var(envp, num_envp, &i,
|
||||||
buffer, buffer_size, &length,
|
buffer, buffer_size, &length,
|
||||||
|
|
|
@ -207,19 +207,6 @@ static int __device_attach(struct device_driver * drv, void * data)
|
||||||
return driver_probe_device(drv, dev);
|
return driver_probe_device(drv, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int device_probe_drivers(void *data)
|
|
||||||
{
|
|
||||||
struct device *dev = data;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (dev->bus) {
|
|
||||||
down(&dev->sem);
|
|
||||||
ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
|
|
||||||
up(&dev->sem);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* device_attach - try to attach device to a driver.
|
* device_attach - try to attach device to a driver.
|
||||||
* @dev: device.
|
* @dev: device.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* firmware_class.c - Multi purpose firmware loading support
|
* firmware_class.c - Multi purpose firmware loading support
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
|
* Copyright (c) 2003 Manuel Estrada Sainz
|
||||||
*
|
*
|
||||||
* Please see Documentation/firmware_class/ for more information.
|
* Please see Documentation/firmware_class/ for more information.
|
||||||
*
|
*
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#define to_dev(obj) container_of(obj, struct device, kobj)
|
#define to_dev(obj) container_of(obj, struct device, kobj)
|
||||||
|
|
||||||
MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
|
MODULE_AUTHOR("Manuel Estrada Sainz");
|
||||||
MODULE_DESCRIPTION("Multi purpose firmware loading support");
|
MODULE_DESCRIPTION("Multi purpose firmware loading support");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
|
|
@ -202,12 +202,12 @@ int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
|
||||||
|
|
||||||
/* be noisy on error issues */
|
/* be noisy on error issues */
|
||||||
if (error == -EEXIST)
|
if (error == -EEXIST)
|
||||||
printk("kobject_add failed for %s with -EEXIST, "
|
printk(KERN_ERR "kobject_add failed for %s with "
|
||||||
"don't try to register things with the "
|
"-EEXIST, don't try to register things with "
|
||||||
"same name in the same directory.\n",
|
"the same name in the same directory.\n",
|
||||||
kobject_name(kobj));
|
kobject_name(kobj));
|
||||||
else
|
else
|
||||||
printk("kobject_add failed for %s (%d)\n",
|
printk(KERN_ERR "kobject_add failed for %s (%d)\n",
|
||||||
kobject_name(kobj), error);
|
kobject_name(kobj), error);
|
||||||
dump_stack();
|
dump_stack();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue