forked from Minki/linux
Driver core update for 4.1-rc1
Here's the driver-core / kobject / lz4 tree update for 4.1-rc1. Everything here has been in linux-next for a while with no reported issues. It's mostly just coding style cleanups, with other minor changes in here as well, nothing big. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iEYEABECAAYFAlUsHkwACgkQMUfUDdst+ykT2gCfbYRyqG+p+jPJnaintZABv04D atMAn0TFWeyRzlYu/eHpKVnrASUYKxA9 =GwEv -----END PGP SIGNATURE----- Merge tag 'driver-core-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core Pull driver core updates from Greg KH: "Here's the driver-core / kobject / lz4 tree update for 4.1-rc1. Everything here has been in linux-next for a while with no reported issues. It's mostly just coding style cleanups, with other minor changes in here as well, nothing big" * tag 'driver-core-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (32 commits) debugfs: allow bad parent pointers to be passed in stable_kernel_rules: Add clause about specification of kernel versions to patch. kobject: WARN as tip when call kobject_get() to a kobject not initialized lib/lz4: Pull out constant tables drivers: platform: parse IRQ flags from resources driver core: Make probe deferral more quiet drivers/core/of: Add symlink to device-tree from devices with an OF node device: Add dev_of_node() accessor drivers: base: fw: fix ret value when loading fw firmware: Avoid manual device_create_file() calls drivers/base: cacheinfo: validate device node for all the caches drivers/base: use tabs where possible in code indentation driver core: add missing blank line after declaration drivers: base: node: Delete space after pointer declaration drivers: base: memory: Use tabs instead of spaces firmware_class: Fix whitespace and indentation drivers: base: dma-mapping: Erase blank space after pointer drivers: base: class: Add a blank line after declarations attribute_container: fix missing blank lines after declarations drivers: base: memory: Fix switch indent ...
This commit is contained in:
commit
c4be50eee2
10
Documentation/ABI/stable/sysfs-devices
Normal file
10
Documentation/ABI/stable/sysfs-devices
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Note: This documents additional properties of any device beyond what
|
||||||
|
# is documented in Documentation/sysfs-rules.txt
|
||||||
|
|
||||||
|
What: /sys/devices/*/of_path
|
||||||
|
Date: February 2015
|
||||||
|
Contact: Device Tree mailing list <devicetree@vger.kernel.org>
|
||||||
|
Description:
|
||||||
|
Any device associated with a device-tree node will have
|
||||||
|
an of_path symlink pointing to the corresponding device
|
||||||
|
node in /sys/firmware/devicetree/
|
|
@ -81,6 +81,16 @@ format in the sign-off area:
|
||||||
git cherry-pick fd21073
|
git cherry-pick fd21073
|
||||||
git cherry-pick <this commit>
|
git cherry-pick <this commit>
|
||||||
|
|
||||||
|
Also, some patches may have kernel version prerequisites. This can be
|
||||||
|
specified in the following format in the sign-off area:
|
||||||
|
|
||||||
|
Cc: <stable@vger.kernel.org> # 3.3.x-
|
||||||
|
|
||||||
|
The tag has the meaning of:
|
||||||
|
git cherry-pick <this commit>
|
||||||
|
|
||||||
|
For each "-stable" tree starting with the specified version.
|
||||||
|
|
||||||
Following the submission:
|
Following the submission:
|
||||||
|
|
||||||
- The sender will receive an ACK when the patch has been accepted into the
|
- The sender will receive an ACK when the patch has been accepted into the
|
||||||
|
|
|
@ -94,6 +94,7 @@ int
|
||||||
attribute_container_unregister(struct attribute_container *cont)
|
attribute_container_unregister(struct attribute_container *cont)
|
||||||
{
|
{
|
||||||
int retval = -EBUSY;
|
int retval = -EBUSY;
|
||||||
|
|
||||||
mutex_lock(&attribute_container_mutex);
|
mutex_lock(&attribute_container_mutex);
|
||||||
spin_lock(&cont->containers.k_lock);
|
spin_lock(&cont->containers.k_lock);
|
||||||
if (!list_empty(&cont->containers.k_list))
|
if (!list_empty(&cont->containers.k_list))
|
||||||
|
@ -349,6 +350,7 @@ int
|
||||||
attribute_container_add_class_device(struct device *classdev)
|
attribute_container_add_class_device(struct device *classdev)
|
||||||
{
|
{
|
||||||
int error = device_add(classdev);
|
int error = device_add(classdev);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
return attribute_container_add_attrs(classdev);
|
return attribute_container_add_attrs(classdev);
|
||||||
|
|
|
@ -515,11 +515,11 @@ int bus_add_device(struct device *dev)
|
||||||
goto out_put;
|
goto out_put;
|
||||||
error = device_add_groups(dev, bus->dev_groups);
|
error = device_add_groups(dev, bus->dev_groups);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_groups;
|
goto out_id;
|
||||||
error = sysfs_create_link(&bus->p->devices_kset->kobj,
|
error = sysfs_create_link(&bus->p->devices_kset->kobj,
|
||||||
&dev->kobj, dev_name(dev));
|
&dev->kobj, dev_name(dev));
|
||||||
if (error)
|
if (error)
|
||||||
goto out_id;
|
goto out_groups;
|
||||||
error = sysfs_create_link(&dev->kobj,
|
error = sysfs_create_link(&dev->kobj,
|
||||||
&dev->bus->p->subsys.kobj, "subsystem");
|
&dev->bus->p->subsys.kobj, "subsystem");
|
||||||
if (error)
|
if (error)
|
||||||
|
|
|
@ -62,15 +62,21 @@ static int cache_setup_of_node(unsigned int cpu)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (np && index < cache_leaves(cpu)) {
|
while (index < cache_leaves(cpu)) {
|
||||||
this_leaf = this_cpu_ci->info_list + index;
|
this_leaf = this_cpu_ci->info_list + index;
|
||||||
if (this_leaf->level != 1)
|
if (this_leaf->level != 1)
|
||||||
np = of_find_next_cache_node(np);
|
np = of_find_next_cache_node(np);
|
||||||
else
|
else
|
||||||
np = of_node_get(np);/* cpu node itself */
|
np = of_node_get(np);/* cpu node itself */
|
||||||
|
if (!np)
|
||||||
|
break;
|
||||||
this_leaf->of_node = np;
|
this_leaf->of_node = np;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (index != cache_leaves(cpu)) /* not all OF nodes populated */
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +195,11 @@ static int detect_cache_attributes(unsigned int cpu)
|
||||||
* will be set up here only if they are not populated already
|
* will be set up here only if they are not populated already
|
||||||
*/
|
*/
|
||||||
ret = cache_shared_cpu_map_setup(cpu);
|
ret = cache_shared_cpu_map_setup(cpu);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
pr_warn("Unable to detect cache hierarcy from DT for CPU %d\n",
|
||||||
|
cpu);
|
||||||
goto free_ci;
|
goto free_ci;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_ci:
|
free_ci:
|
||||||
|
|
|
@ -90,6 +90,7 @@ int class_create_file_ns(struct class *cls, const struct class_attribute *attr,
|
||||||
const void *ns)
|
const void *ns)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (cls)
|
if (cls)
|
||||||
error = sysfs_create_file_ns(&cls->p->subsys.kobj,
|
error = sysfs_create_file_ns(&cls->p->subsys.kobj,
|
||||||
&attr->attr, ns);
|
&attr->attr, ns);
|
||||||
|
@ -488,6 +489,7 @@ ssize_t show_class_attr_string(struct class *class,
|
||||||
struct class_attribute *attr, char *buf)
|
struct class_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct class_attribute_string *cs;
|
struct class_attribute_string *cs;
|
||||||
|
|
||||||
cs = container_of(attr, struct class_attribute_string, attr);
|
cs = container_of(attr, struct class_attribute_string, attr);
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n", cs->str);
|
return snprintf(buf, PAGE_SIZE, "%s\n", cs->str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -805,8 +805,16 @@ static void cleanup_device_parent(struct device *dev)
|
||||||
|
|
||||||
static int device_add_class_symlinks(struct device *dev)
|
static int device_add_class_symlinks(struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct device_node *of_node = dev_of_node(dev);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
if (of_node) {
|
||||||
|
error = sysfs_create_link(&dev->kobj, &of_node->kobj,"of_node");
|
||||||
|
if (error)
|
||||||
|
dev_warn(dev, "Error %d creating of_node link\n",error);
|
||||||
|
/* An error here doesn't warrant bringing down the device */
|
||||||
|
}
|
||||||
|
|
||||||
if (!dev->class)
|
if (!dev->class)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -814,7 +822,7 @@ static int device_add_class_symlinks(struct device *dev)
|
||||||
&dev->class->p->subsys.kobj,
|
&dev->class->p->subsys.kobj,
|
||||||
"subsystem");
|
"subsystem");
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out_devnode;
|
||||||
|
|
||||||
if (dev->parent && device_is_not_partition(dev)) {
|
if (dev->parent && device_is_not_partition(dev)) {
|
||||||
error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
|
error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
|
||||||
|
@ -842,12 +850,16 @@ out_device:
|
||||||
|
|
||||||
out_subsys:
|
out_subsys:
|
||||||
sysfs_remove_link(&dev->kobj, "subsystem");
|
sysfs_remove_link(&dev->kobj, "subsystem");
|
||||||
out:
|
out_devnode:
|
||||||
|
sysfs_remove_link(&dev->kobj, "of_node");
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_remove_class_symlinks(struct device *dev)
|
static void device_remove_class_symlinks(struct device *dev)
|
||||||
{
|
{
|
||||||
|
if (dev_of_node(dev))
|
||||||
|
sysfs_remove_link(&dev->kobj, "of_node");
|
||||||
|
|
||||||
if (!dev->class)
|
if (!dev->class)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1095,8 +1107,7 @@ done:
|
||||||
kobject_del(&dev->kobj);
|
kobject_del(&dev->kobj);
|
||||||
Error:
|
Error:
|
||||||
cleanup_device_parent(dev);
|
cleanup_device_parent(dev);
|
||||||
if (parent)
|
put_device(parent);
|
||||||
put_device(parent);
|
|
||||||
name_error:
|
name_error:
|
||||||
kfree(dev->p);
|
kfree(dev->p);
|
||||||
dev->p = NULL;
|
dev->p = NULL;
|
||||||
|
|
|
@ -320,21 +320,25 @@ probe_failed:
|
||||||
dev->driver = NULL;
|
dev->driver = NULL;
|
||||||
dev_set_drvdata(dev, NULL);
|
dev_set_drvdata(dev, NULL);
|
||||||
|
|
||||||
if (ret == -EPROBE_DEFER) {
|
switch (ret) {
|
||||||
|
case -EPROBE_DEFER:
|
||||||
/* Driver requested deferred probing */
|
/* Driver requested deferred probing */
|
||||||
dev_info(dev, "Driver %s requests probe deferral\n", drv->name);
|
dev_dbg(dev, "Driver %s requests probe deferral\n", drv->name);
|
||||||
driver_deferred_probe_add(dev);
|
driver_deferred_probe_add(dev);
|
||||||
/* Did a trigger occur while probing? Need to re-trigger if yes */
|
/* Did a trigger occur while probing? Need to re-trigger if yes */
|
||||||
if (local_trigger_count != atomic_read(&deferred_trigger_count))
|
if (local_trigger_count != atomic_read(&deferred_trigger_count))
|
||||||
driver_deferred_probe_trigger();
|
driver_deferred_probe_trigger();
|
||||||
} else if (ret != -ENODEV && ret != -ENXIO) {
|
break;
|
||||||
|
case -ENODEV:
|
||||||
|
case -ENXIO:
|
||||||
|
pr_debug("%s: probe of %s rejects match %d\n",
|
||||||
|
drv->name, dev_name(dev), ret);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
/* driver matched but the probe failed */
|
/* driver matched but the probe failed */
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"%s: probe of %s failed with error %d\n",
|
"%s: probe of %s failed with error %d\n",
|
||||||
drv->name, dev_name(dev), ret);
|
drv->name, dev_name(dev), ret);
|
||||||
} else {
|
|
||||||
pr_debug("%s: probe of %s rejects match %d\n",
|
|
||||||
drv->name, dev_name(dev), ret);
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Ignore errors returned by ->probe so that the next driver can try
|
* Ignore errors returned by ->probe so that the next driver can try
|
||||||
|
|
|
@ -62,7 +62,7 @@ static int dmam_match(struct device *dev, void *res, void *match_data)
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* Pointer to allocated memory on success, NULL on failure.
|
* Pointer to allocated memory on success, NULL on failure.
|
||||||
*/
|
*/
|
||||||
void * dmam_alloc_coherent(struct device *dev, size_t size,
|
void *dmam_alloc_coherent(struct device *dev, size_t size,
|
||||||
dma_addr_t *dma_handle, gfp_t gfp)
|
dma_addr_t *dma_handle, gfp_t gfp)
|
||||||
{
|
{
|
||||||
struct dma_devres *dr;
|
struct dma_devres *dr;
|
||||||
|
|
|
@ -103,6 +103,7 @@ int driver_create_file(struct device_driver *drv,
|
||||||
const struct driver_attribute *attr)
|
const struct driver_attribute *attr)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (drv)
|
if (drv)
|
||||||
error = sysfs_create_file(&drv->p->kobj, &attr->attr);
|
error = sysfs_create_file(&drv->p->kobj, &attr->attr);
|
||||||
else
|
else
|
||||||
|
|
|
@ -181,7 +181,7 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name,
|
||||||
{
|
{
|
||||||
struct firmware_buf *buf;
|
struct firmware_buf *buf;
|
||||||
|
|
||||||
buf = kzalloc(sizeof(*buf) + strlen(fw_name) + 1 , GFP_ATOMIC);
|
buf = kzalloc(sizeof(*buf) + strlen(fw_name) + 1, GFP_ATOMIC);
|
||||||
|
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return buf;
|
return buf;
|
||||||
|
@ -835,6 +835,26 @@ static struct bin_attribute firmware_attr_data = {
|
||||||
.write = firmware_data_write,
|
.write = firmware_data_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct attribute *fw_dev_attrs[] = {
|
||||||
|
&dev_attr_loading.attr,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bin_attribute *fw_dev_bin_attrs[] = {
|
||||||
|
&firmware_attr_data,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group fw_dev_attr_group = {
|
||||||
|
.attrs = fw_dev_attrs,
|
||||||
|
.bin_attrs = fw_dev_bin_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group *fw_dev_attr_groups[] = {
|
||||||
|
&fw_dev_attr_group,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
static struct firmware_priv *
|
static struct firmware_priv *
|
||||||
fw_create_instance(struct firmware *firmware, const char *fw_name,
|
fw_create_instance(struct firmware *firmware, const char *fw_name,
|
||||||
struct device *device, unsigned int opt_flags)
|
struct device *device, unsigned int opt_flags)
|
||||||
|
@ -856,6 +876,7 @@ fw_create_instance(struct firmware *firmware, const char *fw_name,
|
||||||
dev_set_name(f_dev, "%s", fw_name);
|
dev_set_name(f_dev, "%s", fw_name);
|
||||||
f_dev->parent = device;
|
f_dev->parent = device;
|
||||||
f_dev->class = &firmware_class;
|
f_dev->class = &firmware_class;
|
||||||
|
f_dev->groups = fw_dev_attr_groups;
|
||||||
exit:
|
exit:
|
||||||
return fw_priv;
|
return fw_priv;
|
||||||
}
|
}
|
||||||
|
@ -879,25 +900,10 @@ static int _request_firmware_load(struct firmware_priv *fw_priv,
|
||||||
goto err_put_dev;
|
goto err_put_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = device_create_bin_file(f_dev, &firmware_attr_data);
|
|
||||||
if (retval) {
|
|
||||||
dev_err(f_dev, "%s: sysfs_create_bin_file failed\n", __func__);
|
|
||||||
goto err_del_dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&fw_lock);
|
mutex_lock(&fw_lock);
|
||||||
list_add(&buf->pending_list, &pending_fw_head);
|
list_add(&buf->pending_list, &pending_fw_head);
|
||||||
mutex_unlock(&fw_lock);
|
mutex_unlock(&fw_lock);
|
||||||
|
|
||||||
retval = device_create_file(f_dev, &dev_attr_loading);
|
|
||||||
if (retval) {
|
|
||||||
mutex_lock(&fw_lock);
|
|
||||||
list_del_init(&buf->pending_list);
|
|
||||||
mutex_unlock(&fw_lock);
|
|
||||||
dev_err(f_dev, "%s: device_create_file failed\n", __func__);
|
|
||||||
goto err_del_bin_attr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt_flags & FW_OPT_UEVENT) {
|
if (opt_flags & FW_OPT_UEVENT) {
|
||||||
buf->need_uevent = true;
|
buf->need_uevent = true;
|
||||||
dev_set_uevent_suppress(f_dev, false);
|
dev_set_uevent_suppress(f_dev, false);
|
||||||
|
@ -913,6 +919,8 @@ static int _request_firmware_load(struct firmware_priv *fw_priv,
|
||||||
mutex_lock(&fw_lock);
|
mutex_lock(&fw_lock);
|
||||||
fw_load_abort(fw_priv);
|
fw_load_abort(fw_priv);
|
||||||
mutex_unlock(&fw_lock);
|
mutex_unlock(&fw_lock);
|
||||||
|
} else if (retval > 0) {
|
||||||
|
retval = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_fw_load_aborted(buf))
|
if (is_fw_load_aborted(buf))
|
||||||
|
@ -920,10 +928,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv,
|
||||||
else if (!buf->data)
|
else if (!buf->data)
|
||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
|
|
||||||
device_remove_file(f_dev, &dev_attr_loading);
|
|
||||||
err_del_bin_attr:
|
|
||||||
device_remove_bin_file(f_dev, &firmware_attr_data);
|
|
||||||
err_del_dev:
|
|
||||||
device_del(f_dev);
|
device_del(f_dev);
|
||||||
err_put_dev:
|
err_put_dev:
|
||||||
put_device(f_dev);
|
put_device(f_dev);
|
||||||
|
@ -1168,7 +1172,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
||||||
**/
|
**/
|
||||||
int
|
int
|
||||||
request_firmware(const struct firmware **firmware_p, const char *name,
|
request_firmware(const struct firmware **firmware_p, const char *name,
|
||||||
struct device *device)
|
struct device *device)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -1196,6 +1200,7 @@ int request_firmware_direct(const struct firmware **firmware_p,
|
||||||
const char *name, struct device *device)
|
const char *name, struct device *device)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
__module_get(THIS_MODULE);
|
__module_get(THIS_MODULE);
|
||||||
ret = _request_firmware(firmware_p, name, device,
|
ret = _request_firmware(firmware_p, name, device,
|
||||||
FW_OPT_UEVENT | FW_OPT_NO_WARN);
|
FW_OPT_UEVENT | FW_OPT_NO_WARN);
|
||||||
|
@ -1276,7 +1281,7 @@ request_firmware_nowait(
|
||||||
{
|
{
|
||||||
struct firmware_work *fw_work;
|
struct firmware_work *fw_work;
|
||||||
|
|
||||||
fw_work = kzalloc(sizeof (struct firmware_work), gfp);
|
fw_work = kzalloc(sizeof(struct firmware_work), gfp);
|
||||||
if (!fw_work)
|
if (!fw_work)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
|
||||||
if (n > 255)
|
if (n > 255)
|
||||||
n = 255;
|
n = 255;
|
||||||
|
|
||||||
p = kmalloc(sizeof(struct probe) * n, GFP_KERNEL);
|
p = kmalloc_array(n, sizeof(struct probe), GFP_KERNEL);
|
||||||
|
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -52,13 +52,13 @@ static BLOCKING_NOTIFIER_HEAD(memory_chain);
|
||||||
|
|
||||||
int register_memory_notifier(struct notifier_block *nb)
|
int register_memory_notifier(struct notifier_block *nb)
|
||||||
{
|
{
|
||||||
return blocking_notifier_chain_register(&memory_chain, nb);
|
return blocking_notifier_chain_register(&memory_chain, nb);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(register_memory_notifier);
|
EXPORT_SYMBOL(register_memory_notifier);
|
||||||
|
|
||||||
void unregister_memory_notifier(struct notifier_block *nb)
|
void unregister_memory_notifier(struct notifier_block *nb)
|
||||||
{
|
{
|
||||||
blocking_notifier_chain_unregister(&memory_chain, nb);
|
blocking_notifier_chain_unregister(&memory_chain, nb);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(unregister_memory_notifier);
|
EXPORT_SYMBOL(unregister_memory_notifier);
|
||||||
|
|
||||||
|
@ -152,20 +152,20 @@ static ssize_t show_mem_state(struct device *dev,
|
||||||
* so that they're not open-coded
|
* so that they're not open-coded
|
||||||
*/
|
*/
|
||||||
switch (mem->state) {
|
switch (mem->state) {
|
||||||
case MEM_ONLINE:
|
case MEM_ONLINE:
|
||||||
len = sprintf(buf, "online\n");
|
len = sprintf(buf, "online\n");
|
||||||
break;
|
break;
|
||||||
case MEM_OFFLINE:
|
case MEM_OFFLINE:
|
||||||
len = sprintf(buf, "offline\n");
|
len = sprintf(buf, "offline\n");
|
||||||
break;
|
break;
|
||||||
case MEM_GOING_OFFLINE:
|
case MEM_GOING_OFFLINE:
|
||||||
len = sprintf(buf, "going-offline\n");
|
len = sprintf(buf, "going-offline\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
len = sprintf(buf, "ERROR-UNKNOWN-%ld\n",
|
len = sprintf(buf, "ERROR-UNKNOWN-%ld\n",
|
||||||
mem->state);
|
mem->state);
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
|
@ -232,19 +232,19 @@ memory_block_action(unsigned long phys_index, unsigned long action, int online_t
|
||||||
first_page = pfn_to_page(start_pfn);
|
first_page = pfn_to_page(start_pfn);
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case MEM_ONLINE:
|
case MEM_ONLINE:
|
||||||
if (!pages_correctly_reserved(start_pfn))
|
if (!pages_correctly_reserved(start_pfn))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
ret = online_pages(start_pfn, nr_pages, online_type);
|
ret = online_pages(start_pfn, nr_pages, online_type);
|
||||||
break;
|
break;
|
||||||
case MEM_OFFLINE:
|
case MEM_OFFLINE:
|
||||||
ret = offline_pages(start_pfn, nr_pages);
|
ret = offline_pages(start_pfn, nr_pages);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: "
|
WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: "
|
||||||
"%ld\n", __func__, phys_index, action, action);
|
"%ld\n", __func__, phys_index, action, action);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -180,7 +180,7 @@ static ssize_t node_read_vmstat(struct device *dev,
|
||||||
static DEVICE_ATTR(vmstat, S_IRUGO, node_read_vmstat, NULL);
|
static DEVICE_ATTR(vmstat, S_IRUGO, node_read_vmstat, NULL);
|
||||||
|
|
||||||
static ssize_t node_read_distance(struct device *dev,
|
static ssize_t node_read_distance(struct device *dev,
|
||||||
struct device_attribute *attr, char * buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
int nid = dev->id;
|
int nid = dev->id;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
@ -200,6 +200,17 @@ static ssize_t node_read_distance(struct device *dev,
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR(distance, S_IRUGO, node_read_distance, NULL);
|
static DEVICE_ATTR(distance, S_IRUGO, node_read_distance, NULL);
|
||||||
|
|
||||||
|
static struct attribute *node_dev_attrs[] = {
|
||||||
|
&dev_attr_cpumap.attr,
|
||||||
|
&dev_attr_cpulist.attr,
|
||||||
|
&dev_attr_meminfo.attr,
|
||||||
|
&dev_attr_numastat.attr,
|
||||||
|
&dev_attr_distance.attr,
|
||||||
|
&dev_attr_vmstat.attr,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
ATTRIBUTE_GROUPS(node_dev);
|
||||||
|
|
||||||
#ifdef CONFIG_HUGETLBFS
|
#ifdef CONFIG_HUGETLBFS
|
||||||
/*
|
/*
|
||||||
* hugetlbfs per node attributes registration interface:
|
* hugetlbfs per node attributes registration interface:
|
||||||
|
@ -273,16 +284,10 @@ static int register_node(struct node *node, int num, struct node *parent)
|
||||||
node->dev.id = num;
|
node->dev.id = num;
|
||||||
node->dev.bus = &node_subsys;
|
node->dev.bus = &node_subsys;
|
||||||
node->dev.release = node_device_release;
|
node->dev.release = node_device_release;
|
||||||
|
node->dev.groups = node_dev_groups;
|
||||||
error = device_register(&node->dev);
|
error = device_register(&node->dev);
|
||||||
|
|
||||||
if (!error){
|
if (!error){
|
||||||
device_create_file(&node->dev, &dev_attr_cpumap);
|
|
||||||
device_create_file(&node->dev, &dev_attr_cpulist);
|
|
||||||
device_create_file(&node->dev, &dev_attr_meminfo);
|
|
||||||
device_create_file(&node->dev, &dev_attr_numastat);
|
|
||||||
device_create_file(&node->dev, &dev_attr_distance);
|
|
||||||
device_create_file(&node->dev, &dev_attr_vmstat);
|
|
||||||
|
|
||||||
hugetlb_register_node(node);
|
hugetlb_register_node(node);
|
||||||
|
|
||||||
compaction_register_node(node);
|
compaction_register_node(node);
|
||||||
|
@ -299,13 +304,6 @@ static int register_node(struct node *node, int num, struct node *parent)
|
||||||
*/
|
*/
|
||||||
void unregister_node(struct node *node)
|
void unregister_node(struct node *node)
|
||||||
{
|
{
|
||||||
device_remove_file(&node->dev, &dev_attr_cpumap);
|
|
||||||
device_remove_file(&node->dev, &dev_attr_cpulist);
|
|
||||||
device_remove_file(&node->dev, &dev_attr_meminfo);
|
|
||||||
device_remove_file(&node->dev, &dev_attr_numastat);
|
|
||||||
device_remove_file(&node->dev, &dev_attr_distance);
|
|
||||||
device_remove_file(&node->dev, &dev_attr_vmstat);
|
|
||||||
|
|
||||||
hugetlb_unregister_node(node); /* no-op, if memoryless node */
|
hugetlb_unregister_node(node); /* no-op, if memoryless node */
|
||||||
|
|
||||||
device_unregister(&node->dev);
|
device_unregister(&node->dev);
|
||||||
|
|
|
@ -101,6 +101,15 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
|
||||||
}
|
}
|
||||||
|
|
||||||
r = platform_get_resource(dev, IORESOURCE_IRQ, num);
|
r = platform_get_resource(dev, IORESOURCE_IRQ, num);
|
||||||
|
/*
|
||||||
|
* The resources may pass trigger flags to the irqs that need
|
||||||
|
* to be set up. It so happens that the trigger flags for
|
||||||
|
* IORESOURCE_BITS correspond 1-to-1 to the IRQF_TRIGGER*
|
||||||
|
* settings.
|
||||||
|
*/
|
||||||
|
if (r && r->flags & IORESOURCE_BITS)
|
||||||
|
irqd_set_trigger_type(irq_get_irq_data(r->start),
|
||||||
|
r->flags & IORESOURCE_BITS);
|
||||||
|
|
||||||
return r ? r->start : -ENXIO;
|
return r ? r->start : -ENXIO;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -365,7 +365,7 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode,
|
||||||
const char *propname, const char **val)
|
const char *propname, const char **val)
|
||||||
{
|
{
|
||||||
if (is_of_node(fwnode))
|
if (is_of_node(fwnode))
|
||||||
return of_property_read_string(of_node(fwnode),propname, val);
|
return of_property_read_string(of_node(fwnode), propname, val);
|
||||||
else if (is_acpi_node(fwnode))
|
else if (is_acpi_node(fwnode))
|
||||||
return acpi_dev_prop_read(acpi_node(fwnode), propname,
|
return acpi_dev_prop_read(acpi_node(fwnode), propname,
|
||||||
DEV_PROP_STRING, val, 1);
|
DEV_PROP_STRING, val, 1);
|
||||||
|
|
|
@ -43,8 +43,8 @@ struct device *soc_device_to_device(struct soc_device *soc_dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static umode_t soc_attribute_mode(struct kobject *kobj,
|
static umode_t soc_attribute_mode(struct kobject *kobj,
|
||||||
struct attribute *attr,
|
struct attribute *attr,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
struct device *dev = container_of(kobj, struct device, kobj);
|
struct device *dev = container_of(kobj, struct device, kobj);
|
||||||
struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
|
struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
|
||||||
|
@ -60,7 +60,7 @@ static umode_t soc_attribute_mode(struct kobject *kobj,
|
||||||
return attr->mode;
|
return attr->mode;
|
||||||
if ((attr == &dev_attr_soc_id.attr)
|
if ((attr == &dev_attr_soc_id.attr)
|
||||||
&& (soc_dev->attr->soc_id != NULL))
|
&& (soc_dev->attr->soc_id != NULL))
|
||||||
return attr->mode;
|
return attr->mode;
|
||||||
|
|
||||||
/* Unknown or unfilled attribute. */
|
/* Unknown or unfilled attribute. */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -117,7 +117,7 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr
|
||||||
|
|
||||||
soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL);
|
soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL);
|
||||||
if (!soc_dev) {
|
if (!soc_dev) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out1;
|
goto out1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr
|
||||||
} while (ret == -EAGAIN);
|
} while (ret == -EAGAIN);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out2;
|
goto out2;
|
||||||
|
|
||||||
soc_dev->attr = soc_dev_attr;
|
soc_dev->attr = soc_dev_attr;
|
||||||
soc_dev->dev.bus = &soc_bus_type;
|
soc_dev->dev.bus = &soc_bus_type;
|
||||||
|
|
|
@ -254,6 +254,9 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
|
||||||
|
|
||||||
pr_debug("debugfs: creating file '%s'\n",name);
|
pr_debug("debugfs: creating file '%s'\n",name);
|
||||||
|
|
||||||
|
if (IS_ERR(parent))
|
||||||
|
return parent;
|
||||||
|
|
||||||
error = simple_pin_fs(&debug_fs_type, &debugfs_mount,
|
error = simple_pin_fs(&debug_fs_type, &debugfs_mount,
|
||||||
&debugfs_mount_count);
|
&debugfs_mount_count);
|
||||||
if (error)
|
if (error)
|
||||||
|
|
|
@ -41,7 +41,7 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
|
||||||
|
|
||||||
if (grp->attrs) {
|
if (grp->attrs) {
|
||||||
for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) {
|
for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) {
|
||||||
umode_t mode = 0;
|
umode_t mode = (*attr)->mode;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In update mode, we're changing the permissions or
|
* In update mode, we're changing the permissions or
|
||||||
|
@ -55,9 +55,14 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
|
||||||
if (!mode)
|
if (!mode)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WARN(mode & ~(SYSFS_PREALLOC | 0664),
|
||||||
|
"Attribute %s: Invalid permissions 0%o\n",
|
||||||
|
(*attr)->name, mode);
|
||||||
|
|
||||||
|
mode &= SYSFS_PREALLOC | 0664;
|
||||||
error = sysfs_add_file_mode_ns(parent, *attr, false,
|
error = sysfs_add_file_mode_ns(parent, *attr, false,
|
||||||
(*attr)->mode | mode,
|
mode, NULL);
|
||||||
NULL);
|
|
||||||
if (unlikely(error))
|
if (unlikely(error))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -916,6 +916,13 @@ static inline void device_lock_assert(struct device *dev)
|
||||||
lockdep_assert_held(&dev->mutex);
|
lockdep_assert_held(&dev->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct device_node *dev_of_node(struct device *dev)
|
||||||
|
{
|
||||||
|
if (!IS_ENABLED(CONFIG_OF))
|
||||||
|
return NULL;
|
||||||
|
return dev->of_node;
|
||||||
|
}
|
||||||
|
|
||||||
void driver_init(void);
|
void driver_init(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -57,6 +57,21 @@ do { \
|
||||||
#define sysfs_attr_init(attr) do {} while (0)
|
#define sysfs_attr_init(attr) do {} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct attribute_group - data structure used to declare an attribute group.
|
||||||
|
* @name: Optional: Attribute group name
|
||||||
|
* If specified, the attribute group will be created in
|
||||||
|
* a new subdirectory with this name.
|
||||||
|
* @is_visible: Optional: Function to return permissions associated with an
|
||||||
|
* attribute of the group. Will be called repeatedly for each
|
||||||
|
* attribute in the group. Only read/write permissions as well as
|
||||||
|
* SYSFS_PREALLOC are accepted. Must return 0 if an attribute is
|
||||||
|
* not visible. The returned value will replace static permissions
|
||||||
|
* defined in struct attribute or struct bin_attribute.
|
||||||
|
* @attrs: Pointer to NULL terminated list of attributes.
|
||||||
|
* @bin_attrs: Pointer to NULL terminated list of binary attributes.
|
||||||
|
* Either attrs or bin_attrs or both must be provided.
|
||||||
|
*/
|
||||||
struct attribute_group {
|
struct attribute_group {
|
||||||
const char *name;
|
const char *name;
|
||||||
umode_t (*is_visible)(struct kobject *,
|
umode_t (*is_visible)(struct kobject *,
|
||||||
|
|
|
@ -576,8 +576,13 @@ void kobject_del(struct kobject *kobj)
|
||||||
*/
|
*/
|
||||||
struct kobject *kobject_get(struct kobject *kobj)
|
struct kobject *kobject_get(struct kobject *kobj)
|
||||||
{
|
{
|
||||||
if (kobj)
|
if (kobj) {
|
||||||
|
if (!kobj->state_initialized)
|
||||||
|
WARN(1, KERN_WARNING "kobject: '%s' (%p): is not "
|
||||||
|
"initialized, yet kobject_get() is being "
|
||||||
|
"called.\n", kobject_name(kobj), kobj);
|
||||||
kref_get(&kobj->kref);
|
kref_get(&kobj->kref);
|
||||||
|
}
|
||||||
return kobj;
|
return kobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,11 @@
|
||||||
|
|
||||||
#include "lz4defs.h"
|
#include "lz4defs.h"
|
||||||
|
|
||||||
|
static const int dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
|
||||||
|
#if LZ4_ARCH64
|
||||||
|
static const int dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int lz4_uncompress(const char *source, char *dest, int osize)
|
static int lz4_uncompress(const char *source, char *dest, int osize)
|
||||||
{
|
{
|
||||||
const BYTE *ip = (const BYTE *) source;
|
const BYTE *ip = (const BYTE *) source;
|
||||||
|
@ -56,10 +61,6 @@ static int lz4_uncompress(const char *source, char *dest, int osize)
|
||||||
BYTE *cpy;
|
BYTE *cpy;
|
||||||
unsigned token;
|
unsigned token;
|
||||||
size_t length;
|
size_t length;
|
||||||
size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
|
|
||||||
#if LZ4_ARCH64
|
|
||||||
size_t dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
|
@ -116,7 +117,7 @@ static int lz4_uncompress(const char *source, char *dest, int osize)
|
||||||
/* copy repeated sequence */
|
/* copy repeated sequence */
|
||||||
if (unlikely((op - ref) < STEPSIZE)) {
|
if (unlikely((op - ref) < STEPSIZE)) {
|
||||||
#if LZ4_ARCH64
|
#if LZ4_ARCH64
|
||||||
size_t dec64 = dec64table[op - ref];
|
int dec64 = dec64table[op - ref];
|
||||||
#else
|
#else
|
||||||
const int dec64 = 0;
|
const int dec64 = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -177,11 +178,6 @@ static int lz4_uncompress_unknownoutputsize(const char *source, char *dest,
|
||||||
BYTE * const oend = op + maxoutputsize;
|
BYTE * const oend = op + maxoutputsize;
|
||||||
BYTE *cpy;
|
BYTE *cpy;
|
||||||
|
|
||||||
size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
|
|
||||||
#if LZ4_ARCH64
|
|
||||||
size_t dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Main Loop */
|
/* Main Loop */
|
||||||
while (ip < iend) {
|
while (ip < iend) {
|
||||||
|
|
||||||
|
@ -249,7 +245,7 @@ static int lz4_uncompress_unknownoutputsize(const char *source, char *dest,
|
||||||
/* copy repeated sequence */
|
/* copy repeated sequence */
|
||||||
if (unlikely((op - ref) < STEPSIZE)) {
|
if (unlikely((op - ref) < STEPSIZE)) {
|
||||||
#if LZ4_ARCH64
|
#if LZ4_ARCH64
|
||||||
size_t dec64 = dec64table[op - ref];
|
int dec64 = dec64table[op - ref];
|
||||||
#else
|
#else
|
||||||
const int dec64 = 0;
|
const int dec64 = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,7 +36,12 @@ static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,
|
||||||
static ssize_t foo_store(struct kobject *kobj, struct kobj_attribute *attr,
|
static ssize_t foo_store(struct kobject *kobj, struct kobj_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
sscanf(buf, "%du", &foo);
|
int ret;
|
||||||
|
|
||||||
|
ret = kstrtoint(buf, 10, &foo);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,9 +68,12 @@ static ssize_t b_show(struct kobject *kobj, struct kobj_attribute *attr,
|
||||||
static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr,
|
static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
int var;
|
int var, ret;
|
||||||
|
|
||||||
|
ret = kstrtoint(buf, 10, &var);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
sscanf(buf, "%du", &var);
|
|
||||||
if (strcmp(attr->attr.name, "baz") == 0)
|
if (strcmp(attr->attr.name, "baz") == 0)
|
||||||
baz = var;
|
baz = var;
|
||||||
else
|
else
|
||||||
|
@ -134,5 +142,5 @@ static void __exit example_exit(void)
|
||||||
|
|
||||||
module_init(example_init);
|
module_init(example_init);
|
||||||
module_exit(example_exit);
|
module_exit(example_exit);
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL v2");
|
||||||
MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>");
|
MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>");
|
||||||
|
|
|
@ -120,7 +120,12 @@ static ssize_t foo_show(struct foo_obj *foo_obj, struct foo_attribute *attr,
|
||||||
static ssize_t foo_store(struct foo_obj *foo_obj, struct foo_attribute *attr,
|
static ssize_t foo_store(struct foo_obj *foo_obj, struct foo_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
sscanf(buf, "%du", &foo_obj->foo);
|
int ret;
|
||||||
|
|
||||||
|
ret = kstrtoint(buf, 10, &foo_obj->foo);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,9 +152,12 @@ static ssize_t b_show(struct foo_obj *foo_obj, struct foo_attribute *attr,
|
||||||
static ssize_t b_store(struct foo_obj *foo_obj, struct foo_attribute *attr,
|
static ssize_t b_store(struct foo_obj *foo_obj, struct foo_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
int var;
|
int var, ret;
|
||||||
|
|
||||||
|
ret = kstrtoint(buf, 10, &var);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
sscanf(buf, "%du", &var);
|
|
||||||
if (strcmp(attr->attr.name, "baz") == 0)
|
if (strcmp(attr->attr.name, "baz") == 0)
|
||||||
foo_obj->baz = var;
|
foo_obj->baz = var;
|
||||||
else
|
else
|
||||||
|
@ -277,5 +285,5 @@ static void __exit example_exit(void)
|
||||||
|
|
||||||
module_init(example_init);
|
module_init(example_init);
|
||||||
module_exit(example_exit);
|
module_exit(example_exit);
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL v2");
|
||||||
MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>");
|
MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user