aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/hw_random/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/hw_random/core.c')
-rw-r--r--drivers/char/hw_random/core.c79
1 files changed, 55 insertions, 24 deletions
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 32a8a867f7f8..da8faf78536a 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -179,7 +179,8 @@ skip_init:
add_early_randomness(rng);
current_quality = rng->quality ? : default_quality;
- current_quality &= 1023;
+ if (current_quality > 1024)
+ current_quality = 1024;
if (current_quality == 0 && hwrng_fill)
kthread_stop(hwrng_fill);
@@ -299,11 +300,14 @@ static const struct file_operations rng_chrdev_ops = {
.llseek = noop_llseek,
};
+static const struct attribute_group *rng_dev_groups[];
+
static struct miscdevice rng_miscdev = {
.minor = RNG_MISCDEV_MINOR,
.name = RNG_MODULE_NAME,
.nodename = "hwrng",
.fops = &rng_chrdev_ops,
+ .groups = rng_dev_groups,
};
@@ -376,37 +380,22 @@ static DEVICE_ATTR(rng_available, S_IRUGO,
hwrng_attr_available_show,
NULL);
+static struct attribute *rng_dev_attrs[] = {
+ &dev_attr_rng_current.attr,
+ &dev_attr_rng_available.attr,
+ NULL
+};
+
+ATTRIBUTE_GROUPS(rng_dev);
static void __exit unregister_miscdev(void)
{
- device_remove_file(rng_miscdev.this_device, &dev_attr_rng_available);
- device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current);
misc_deregister(&rng_miscdev);
}
static int __init register_miscdev(void)
{
- int err;
-
- err = misc_register(&rng_miscdev);
- if (err)
- goto out;
- err = device_create_file(rng_miscdev.this_device,
- &dev_attr_rng_current);
- if (err)
- goto err_misc_dereg;
- err = device_create_file(rng_miscdev.this_device,
- &dev_attr_rng_available);
- if (err)
- goto err_remove_current;
-out:
- return err;
-
-err_remove_current:
- device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current);
-err_misc_dereg:
- misc_deregister(&rng_miscdev);
- goto out;
+ return misc_register(&rng_miscdev);
}
static int hwrng_fillfn(void *unused)
@@ -536,6 +525,48 @@ void hwrng_unregister(struct hwrng *rng)
}
EXPORT_SYMBOL_GPL(hwrng_unregister);
+static void devm_hwrng_release(struct device *dev, void *res)
+{
+ hwrng_unregister(*(struct hwrng **)res);
+}
+
+static int devm_hwrng_match(struct device *dev, void *res, void *data)
+{
+ struct hwrng **r = res;
+
+ if (WARN_ON(!r || !*r))
+ return 0;
+
+ return *r == data;
+}
+
+int devm_hwrng_register(struct device *dev, struct hwrng *rng)
+{
+ struct hwrng **ptr;
+ int error;
+
+ ptr = devres_alloc(devm_hwrng_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ error = hwrng_register(rng);
+ if (error) {
+ devres_free(ptr);
+ return error;
+ }
+
+ *ptr = rng;
+ devres_add(dev, ptr);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(devm_hwrng_register);
+
+void devm_hwrng_unregister(struct device *dev, struct hwrng *rng)
+{
+ devres_release(dev, devm_hwrng_release, devm_hwrng_match, rng);
+}
+EXPORT_SYMBOL_GPL(devm_hwrng_unregister);
+
static int __init hwrng_modinit(void)
{
return register_miscdev();