mirror of https://gitee.com/openkylin/linux.git
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: driver core: numa: fix BUILD_BUG_ON for node_read_distance driver-core: document ERR_PTR() return values kobject: documentation: Update to refer to kset-example.c. sysdev: the cpu probe/release attributes should be sysdev_class_attributes kobject: documentation: Fix erroneous example in kobject doc. driver-core: fix missing kernel-doc in firmware_class Driver core: Early platform kernel-doc update sysfs: fix sysfs lockdep warning in mlx4 code sysfs: fix sysfs lockdep warning in infiniband code sysfs: fix sysfs lockdep warning in ipmi code sysfs: Initialised pci bus legacy_mem field before use sysfs: use sysfs_bin_attr_init in firmware class driver
This commit is contained in:
commit
2eb645e7b5
|
@ -59,37 +59,56 @@ nice to have in other objects. The C language does not allow for the
|
|||
direct expression of inheritance, so other techniques - such as structure
|
||||
embedding - must be used.
|
||||
|
||||
So, for example, the UIO code has a structure that defines the memory
|
||||
region associated with a uio device:
|
||||
(As an aside, for those familiar with the kernel linked list implementation,
|
||||
this is analogous as to how "list_head" structs are rarely useful on
|
||||
their own, but are invariably found embedded in the larger objects of
|
||||
interest.)
|
||||
|
||||
struct uio_mem {
|
||||
So, for example, the UIO code in drivers/uio/uio.c has a structure that
|
||||
defines the memory region associated with a uio device:
|
||||
|
||||
struct uio_map {
|
||||
struct kobject kobj;
|
||||
unsigned long addr;
|
||||
unsigned long size;
|
||||
int memtype;
|
||||
void __iomem *internal_addr;
|
||||
};
|
||||
struct uio_mem *mem;
|
||||
};
|
||||
|
||||
If you have a struct uio_mem structure, finding its embedded kobject is
|
||||
If you have a struct uio_map structure, finding its embedded kobject is
|
||||
just a matter of using the kobj member. Code that works with kobjects will
|
||||
often have the opposite problem, however: given a struct kobject pointer,
|
||||
what is the pointer to the containing structure? You must avoid tricks
|
||||
(such as assuming that the kobject is at the beginning of the structure)
|
||||
and, instead, use the container_of() macro, found in <linux/kernel.h>:
|
||||
|
||||
container_of(pointer, type, member)
|
||||
container_of(pointer, type, member)
|
||||
|
||||
where pointer is the pointer to the embedded kobject, type is the type of
|
||||
the containing structure, and member is the name of the structure field to
|
||||
which pointer points. The return value from container_of() is a pointer to
|
||||
the given type. So, for example, a pointer "kp" to a struct kobject
|
||||
embedded within a struct uio_mem could be converted to a pointer to the
|
||||
containing uio_mem structure with:
|
||||
where:
|
||||
|
||||
struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj);
|
||||
* "pointer" is the pointer to the embedded kobject,
|
||||
* "type" is the type of the containing structure, and
|
||||
* "member" is the name of the structure field to which "pointer" points.
|
||||
|
||||
Programmers often define a simple macro for "back-casting" kobject pointers
|
||||
to the containing type.
|
||||
The return value from container_of() is a pointer to the corresponding
|
||||
container type. So, for example, a pointer "kp" to a struct kobject
|
||||
embedded *within* a struct uio_map could be converted to a pointer to the
|
||||
*containing* uio_map structure with:
|
||||
|
||||
struct uio_map *u_map = container_of(kp, struct uio_map, kobj);
|
||||
|
||||
For convenience, programmers often define a simple macro for "back-casting"
|
||||
kobject pointers to the containing type. Exactly this happens in the
|
||||
earlier drivers/uio/uio.c, as you can see here:
|
||||
|
||||
struct uio_map {
|
||||
struct kobject kobj;
|
||||
struct uio_mem *mem;
|
||||
};
|
||||
|
||||
#define to_map(map) container_of(map, struct uio_map, kobj)
|
||||
|
||||
where the macro argument "map" is a pointer to the struct kobject in
|
||||
question. That macro is subsequently invoked with:
|
||||
|
||||
struct uio_map *map = to_map(kobj);
|
||||
|
||||
|
||||
Initialization of kobjects
|
||||
|
@ -387,4 +406,5 @@ called, and the objects in the former circle release each other.
|
|||
Example code to copy from
|
||||
|
||||
For a more complete example of using ksets and kobjects properly, see the
|
||||
sample/kobject/kset-example.c code.
|
||||
example programs samples/kobject/{kobject-example.c,kset-example.c},
|
||||
which will be built as loadable modules if you select CONFIG_SAMPLE_KOBJECT.
|
||||
|
|
|
@ -219,6 +219,8 @@ static void class_create_release(struct class *cls)
|
|||
* This is used to create a struct class pointer that can then be used
|
||||
* in calls to device_create().
|
||||
*
|
||||
* Returns &struct class pointer on success, or ERR_PTR() on error.
|
||||
*
|
||||
* Note, the pointer created here is to be destroyed when finished by
|
||||
* making a call to class_destroy().
|
||||
*/
|
||||
|
|
|
@ -1345,6 +1345,8 @@ static void root_device_release(struct device *dev)
|
|||
* 'module' symlink which points to the @owner directory
|
||||
* in sysfs.
|
||||
*
|
||||
* Returns &struct device pointer on success, or ERR_PTR() on error.
|
||||
*
|
||||
* Note: You probably want to use root_device_register().
|
||||
*/
|
||||
struct device *__root_device_register(const char *name, struct module *owner)
|
||||
|
@ -1432,6 +1434,8 @@ static void device_create_release(struct device *dev)
|
|||
* Any further sysfs files that might be required can be created using this
|
||||
* pointer.
|
||||
*
|
||||
* Returns &struct device pointer on success, or ERR_PTR() on error.
|
||||
*
|
||||
* Note: the struct class passed to this function must have previously
|
||||
* been created with a call to class_create().
|
||||
*/
|
||||
|
@ -1492,6 +1496,8 @@ EXPORT_SYMBOL_GPL(device_create_vargs);
|
|||
* Any further sysfs files that might be required can be created using this
|
||||
* pointer.
|
||||
*
|
||||
* Returns &struct device pointer on success, or ERR_PTR() on error.
|
||||
*
|
||||
* Note: the struct class passed to this function must have previously
|
||||
* been created with a call to class_create().
|
||||
*/
|
||||
|
|
|
@ -79,24 +79,24 @@ void unregister_cpu(struct cpu *cpu)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
|
||||
static ssize_t cpu_probe_store(struct sys_device *dev,
|
||||
struct sysdev_attribute *attr,
|
||||
const char *buf,
|
||||
static ssize_t cpu_probe_store(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
return arch_cpu_probe(buf, count);
|
||||
}
|
||||
|
||||
static ssize_t cpu_release_store(struct sys_device *dev,
|
||||
struct sysdev_attribute *attr,
|
||||
const char *buf,
|
||||
static ssize_t cpu_release_store(struct sysdev_class *class,
|
||||
struct sysdev_class_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
return arch_cpu_release(buf, count);
|
||||
}
|
||||
|
||||
static SYSDEV_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
|
||||
static SYSDEV_ATTR(release, S_IWUSR, NULL, cpu_release_store);
|
||||
static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
|
||||
static SYSDEV_CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
|
||||
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
|
||||
|
||||
#else /* ... !CONFIG_HOTPLUG_CPU */
|
||||
|
|
|
@ -78,6 +78,7 @@ firmware_timeout_show(struct class *class,
|
|||
/**
|
||||
* firmware_timeout_store - set number of seconds to wait for firmware
|
||||
* @class: device class pointer
|
||||
* @attr: device attribute pointer
|
||||
* @buf: buffer to scan for timeout value
|
||||
* @count: number of bytes in @buf
|
||||
*
|
||||
|
@ -442,6 +443,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
|
|||
fw_priv = dev_get_drvdata(f_dev);
|
||||
|
||||
fw_priv->fw = fw;
|
||||
sysfs_bin_attr_init(&fw_priv->attr_data);
|
||||
retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
|
||||
if (retval) {
|
||||
dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
|
||||
|
|
|
@ -165,8 +165,11 @@ static ssize_t node_read_distance(struct sys_device * dev,
|
|||
int len = 0;
|
||||
int i;
|
||||
|
||||
/* buf currently PAGE_SIZE, need ~4 chars per node */
|
||||
BUILD_BUG_ON(MAX_NUMNODES*4 > PAGE_SIZE/2);
|
||||
/*
|
||||
* buf is currently PAGE_SIZE in length and each node needs 4 chars
|
||||
* at the most (distance + space or newline).
|
||||
*/
|
||||
BUILD_BUG_ON(MAX_NUMNODES * 4 > PAGE_SIZE);
|
||||
|
||||
for_each_online_node(i)
|
||||
len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i));
|
||||
|
|
|
@ -362,6 +362,8 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
|
|||
* enumeration tasks, they don't fully conform to the Linux driver model.
|
||||
* In particular, when such drivers are built as modules, they can't be
|
||||
* "hotplugged".
|
||||
*
|
||||
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
|
||||
*/
|
||||
struct platform_device *platform_device_register_simple(const char *name,
|
||||
int id,
|
||||
|
@ -408,6 +410,8 @@ EXPORT_SYMBOL_GPL(platform_device_register_simple);
|
|||
* allocated for the device allows drivers using such devices to be
|
||||
* unloaded without waiting for the last reference to the device to be
|
||||
* dropped.
|
||||
*
|
||||
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
|
||||
*/
|
||||
struct platform_device *platform_device_register_data(
|
||||
struct device *parent,
|
||||
|
@ -559,6 +563,8 @@ EXPORT_SYMBOL_GPL(platform_driver_probe);
|
|||
*
|
||||
* Use this in legacy-style modules that probe hardware directly and
|
||||
* register a single platform device and corresponding platform driver.
|
||||
*
|
||||
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
|
||||
*/
|
||||
struct platform_device * __init_or_module platform_create_bundle(
|
||||
struct platform_driver *driver,
|
||||
|
@ -1052,9 +1058,11 @@ static __initdata LIST_HEAD(early_platform_driver_list);
|
|||
static __initdata LIST_HEAD(early_platform_device_list);
|
||||
|
||||
/**
|
||||
* early_platform_driver_register
|
||||
* early_platform_driver_register - register early platform driver
|
||||
* @epdrv: early_platform driver structure
|
||||
* @buf: string passed from early_param()
|
||||
*
|
||||
* Helper function for early_platform_init() / early_platform_init_buffer()
|
||||
*/
|
||||
int __init early_platform_driver_register(struct early_platform_driver *epdrv,
|
||||
char *buf)
|
||||
|
@ -1106,9 +1114,12 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv,
|
|||
}
|
||||
|
||||
/**
|
||||
* early_platform_add_devices - add a numbers of early platform devices
|
||||
* early_platform_add_devices - adds a number of early platform devices
|
||||
* @devs: array of early platform devices to add
|
||||
* @num: number of early platform devices in array
|
||||
*
|
||||
* Used by early architecture code to register early platform devices and
|
||||
* their platform data.
|
||||
*/
|
||||
void __init early_platform_add_devices(struct platform_device **devs, int num)
|
||||
{
|
||||
|
@ -1128,8 +1139,12 @@ void __init early_platform_add_devices(struct platform_device **devs, int num)
|
|||
}
|
||||
|
||||
/**
|
||||
* early_platform_driver_register_all
|
||||
* early_platform_driver_register_all - register early platform drivers
|
||||
* @class_str: string to identify early platform driver class
|
||||
*
|
||||
* Used by architecture code to register all early platform drivers
|
||||
* for a certain class. If omitted then only early platform drivers
|
||||
* with matching kernel command line class parameters will be registered.
|
||||
*/
|
||||
void __init early_platform_driver_register_all(char *class_str)
|
||||
{
|
||||
|
@ -1151,7 +1166,7 @@ void __init early_platform_driver_register_all(char *class_str)
|
|||
}
|
||||
|
||||
/**
|
||||
* early_platform_match
|
||||
* early_platform_match - find early platform device matching driver
|
||||
* @epdrv: early platform driver structure
|
||||
* @id: id to match against
|
||||
*/
|
||||
|
@ -1169,7 +1184,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id)
|
|||
}
|
||||
|
||||
/**
|
||||
* early_platform_left
|
||||
* early_platform_left - check if early platform driver has matching devices
|
||||
* @epdrv: early platform driver structure
|
||||
* @id: return true if id or above exists
|
||||
*/
|
||||
|
@ -1187,7 +1202,7 @@ static __init int early_platform_left(struct early_platform_driver *epdrv,
|
|||
}
|
||||
|
||||
/**
|
||||
* early_platform_driver_probe_id
|
||||
* early_platform_driver_probe_id - probe drivers matching class_str and id
|
||||
* @class_str: string to identify early platform driver class
|
||||
* @id: id to match against
|
||||
* @nr_probe: number of platform devices to successfully probe before exiting
|
||||
|
@ -1257,10 +1272,14 @@ static int __init early_platform_driver_probe_id(char *class_str,
|
|||
}
|
||||
|
||||
/**
|
||||
* early_platform_driver_probe
|
||||
* early_platform_driver_probe - probe a class of registered drivers
|
||||
* @class_str: string to identify early platform driver class
|
||||
* @nr_probe: number of platform devices to successfully probe before exiting
|
||||
* @user_only: only probe user specified early platform devices
|
||||
*
|
||||
* Used by architecture code to probe registered early platform drivers
|
||||
* within a certain class. For probe to happen a registered early platform
|
||||
* device matching a registered early platform driver is needed.
|
||||
*/
|
||||
int __init early_platform_driver_probe(char *class_str,
|
||||
int nr_probe,
|
||||
|
|
|
@ -2272,42 +2272,52 @@ static int create_files(struct bmc_device *bmc)
|
|||
bmc->device_id_attr.attr.name = "device_id";
|
||||
bmc->device_id_attr.attr.mode = S_IRUGO;
|
||||
bmc->device_id_attr.show = device_id_show;
|
||||
sysfs_attr_init(&bmc->device_id_attr.attr);
|
||||
|
||||
bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
|
||||
bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
|
||||
bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
|
||||
sysfs_attr_init(&bmc->provides_dev_sdrs_attr.attr);
|
||||
|
||||
bmc->revision_attr.attr.name = "revision";
|
||||
bmc->revision_attr.attr.mode = S_IRUGO;
|
||||
bmc->revision_attr.show = revision_show;
|
||||
sysfs_attr_init(&bmc->revision_attr.attr);
|
||||
|
||||
bmc->firmware_rev_attr.attr.name = "firmware_revision";
|
||||
bmc->firmware_rev_attr.attr.mode = S_IRUGO;
|
||||
bmc->firmware_rev_attr.show = firmware_rev_show;
|
||||
sysfs_attr_init(&bmc->firmware_rev_attr.attr);
|
||||
|
||||
bmc->version_attr.attr.name = "ipmi_version";
|
||||
bmc->version_attr.attr.mode = S_IRUGO;
|
||||
bmc->version_attr.show = ipmi_version_show;
|
||||
sysfs_attr_init(&bmc->version_attr.attr);
|
||||
|
||||
bmc->add_dev_support_attr.attr.name = "additional_device_support";
|
||||
bmc->add_dev_support_attr.attr.mode = S_IRUGO;
|
||||
bmc->add_dev_support_attr.show = add_dev_support_show;
|
||||
sysfs_attr_init(&bmc->add_dev_support_attr.attr);
|
||||
|
||||
bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
|
||||
bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
|
||||
bmc->manufacturer_id_attr.show = manufacturer_id_show;
|
||||
sysfs_attr_init(&bmc->manufacturer_id_attr.attr);
|
||||
|
||||
bmc->product_id_attr.attr.name = "product_id";
|
||||
bmc->product_id_attr.attr.mode = S_IRUGO;
|
||||
bmc->product_id_attr.show = product_id_show;
|
||||
sysfs_attr_init(&bmc->product_id_attr.attr);
|
||||
|
||||
bmc->guid_attr.attr.name = "guid";
|
||||
bmc->guid_attr.attr.mode = S_IRUGO;
|
||||
bmc->guid_attr.show = guid_show;
|
||||
sysfs_attr_init(&bmc->guid_attr.attr);
|
||||
|
||||
bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
|
||||
bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
|
||||
bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
|
||||
sysfs_attr_init(&bmc->aux_firmware_rev_attr.attr);
|
||||
|
||||
err = device_create_file(&bmc->dev->dev,
|
||||
&bmc->device_id_attr);
|
||||
|
|
|
@ -461,6 +461,7 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *,
|
|||
element->attr.attr.mode = S_IRUGO;
|
||||
element->attr.show = show;
|
||||
element->index = i;
|
||||
sysfs_attr_init(&element->attr.attr);
|
||||
|
||||
tab_attr[i] = &element->attr.attr;
|
||||
}
|
||||
|
|
|
@ -1023,6 +1023,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
|
|||
info->port_attr.attr.mode = S_IRUGO | S_IWUSR;
|
||||
info->port_attr.show = show_port_type;
|
||||
info->port_attr.store = set_port_type;
|
||||
sysfs_attr_init(&info->port_attr.attr);
|
||||
|
||||
err = device_create_file(&dev->pdev->dev, &info->port_attr);
|
||||
if (err) {
|
||||
|
|
|
@ -655,8 +655,8 @@ void pci_create_legacy_files(struct pci_bus *b)
|
|||
goto legacy_io_err;
|
||||
|
||||
/* Allocated above after the legacy_io struct */
|
||||
sysfs_bin_attr_init(b->legacy_mem);
|
||||
b->legacy_mem = b->legacy_io + 1;
|
||||
sysfs_bin_attr_init(b->legacy_mem);
|
||||
b->legacy_mem->attr.name = "legacy_mem";
|
||||
b->legacy_mem->size = 1024*1024;
|
||||
b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
|
||||
|
|
Loading…
Reference in New Issue