staging: axis-fifo: convert to use miscdevice

Using a struct class, a cdev, and another device just for a single minor
device is total overkill.  Just use a dynamic misc device instead,
saving lots of logic and memory.

Cc: Jacob Feder <jacobsfeder@gmail.com>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Muhammad Usama Anjum <musamaanjum@gmail.com>
Link: https://lore.kernel.org/r/YTdPvBgKW6cKYrvb@kroah.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Greg Kroah-Hartman 2021-09-07 13:40:44 +02:00
parent dfd1a05a38
commit d2d7aa5389
1 changed files with 26 additions and 62 deletions

View File

@ -30,6 +30,7 @@
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/jiffies.h>
#include <linux/miscdevice.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
@ -102,9 +103,6 @@
* globals
* ----------------------------
*/
static struct class *axis_fifo_driver_class; /* char device class */
static int read_timeout = 1000; /* ms to wait before read() times out */
static int write_timeout = 1000; /* ms to wait before write() times out */
@ -140,9 +138,7 @@ struct axis_fifo {
unsigned int read_flags; /* read file flags */
struct device *dt_device; /* device created from the device tree */
struct device *device; /* device associated with char_device */
dev_t devt; /* our char device number */
struct cdev char_device; /* our char device */
struct miscdevice miscdev;
};
/* ----------------------------
@ -319,6 +315,11 @@ static const struct attribute_group axis_fifo_attrs_group = {
.attrs = axis_fifo_attrs,
};
static const struct attribute_group *axis_fifo_attrs_groups[] = {
&axis_fifo_attrs_group,
NULL,
};
/* ----------------------------
* implementation
* ----------------------------
@ -684,8 +685,8 @@ static irqreturn_t axis_fifo_irq(int irq, void *dw)
static int axis_fifo_open(struct inode *inod, struct file *f)
{
struct axis_fifo *fifo = (struct axis_fifo *)container_of(inod->i_cdev,
struct axis_fifo, char_device);
struct axis_fifo *fifo = container_of(f->private_data,
struct axis_fifo, miscdev);
f->private_data = fifo;
if (((f->f_flags & O_ACCMODE) == O_WRONLY) ||
@ -812,9 +813,7 @@ static int axis_fifo_probe(struct platform_device *pdev)
struct resource *r_mem; /* IO mem resources */
struct device *dev = &pdev->dev; /* OS device (from device tree) */
struct axis_fifo *fifo = NULL;
char device_name[32];
char *device_name;
int rc = 0; /* error return value */
/* ----------------------------
@ -822,8 +821,12 @@ static int axis_fifo_probe(struct platform_device *pdev)
* ----------------------------
*/
device_name = devm_kzalloc(dev, 32, GFP_KERNEL);
if (!device_name)
return -ENOMEM;
/* allocate device wrapper memory */
fifo = devm_kmalloc(dev, sizeof(*fifo), GFP_KERNEL);
fifo = devm_kzalloc(dev, sizeof(*fifo), GFP_KERNEL);
if (!fifo)
return -ENOMEM;
@ -859,9 +862,7 @@ static int axis_fifo_probe(struct platform_device *pdev)
dev_dbg(fifo->dt_device, "remapped memory to 0x%p\n", fifo->base_addr);
/* create unique device name */
snprintf(device_name, sizeof(device_name), "%s_%pa",
DRIVER_NAME, &r_mem->start);
snprintf(device_name, 32, "%s_%pa", DRIVER_NAME, &r_mem->start);
dev_dbg(fifo->dt_device, "device name [%s]\n", device_name);
/* ----------------------------
@ -904,51 +905,21 @@ static int axis_fifo_probe(struct platform_device *pdev)
* ----------------------------
*/
/* allocate device number */
rc = alloc_chrdev_region(&fifo->devt, 0, 1, DRIVER_NAME);
/* create character device */
fifo->miscdev.fops = &fops;
fifo->miscdev.minor = MISC_DYNAMIC_MINOR;
fifo->miscdev.name = device_name;
fifo->miscdev.groups = axis_fifo_attrs_groups;
fifo->miscdev.parent = dev;
rc = misc_register(&fifo->miscdev);
if (rc < 0)
goto err_initial;
dev_dbg(fifo->dt_device, "allocated device number major %i minor %i\n",
MAJOR(fifo->devt), MINOR(fifo->devt));
/* create driver file */
fifo->device = device_create(axis_fifo_driver_class, NULL, fifo->devt,
NULL, device_name);
if (IS_ERR(fifo->device)) {
dev_err(fifo->dt_device,
"couldn't create driver file\n");
rc = PTR_ERR(fifo->device);
goto err_chrdev_region;
}
dev_set_drvdata(fifo->device, fifo);
/* create character device */
cdev_init(&fifo->char_device, &fops);
rc = cdev_add(&fifo->char_device, fifo->devt, 1);
if (rc < 0) {
dev_err(fifo->dt_device, "couldn't create character device\n");
goto err_dev;
}
/* create sysfs entries */
rc = devm_device_add_group(fifo->device, &axis_fifo_attrs_group);
if (rc < 0) {
dev_err(fifo->dt_device, "couldn't register sysfs group\n");
goto err_cdev;
}
dev_info(fifo->dt_device, "axis-fifo created at %pa mapped to 0x%pa, irq=%i, major=%i, minor=%i\n",
&r_mem->start, &fifo->base_addr, fifo->irq,
MAJOR(fifo->devt), MINOR(fifo->devt));
dev_info(fifo->dt_device, "axis-fifo created at %pa mapped to 0x%pa, irq=%i\n",
&r_mem->start, &fifo->base_addr, fifo->irq);
return 0;
err_cdev:
cdev_del(&fifo->char_device);
err_dev:
device_destroy(axis_fifo_driver_class, fifo->devt);
err_chrdev_region:
unregister_chrdev_region(fifo->devt, 1);
err_initial:
dev_set_drvdata(dev, NULL);
return rc;
@ -959,10 +930,7 @@ static int axis_fifo_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct axis_fifo *fifo = dev_get_drvdata(dev);
cdev_del(&fifo->char_device);
dev_set_drvdata(fifo->device, NULL);
device_destroy(axis_fifo_driver_class, fifo->devt);
unregister_chrdev_region(fifo->devt, 1);
misc_deregister(&fifo->miscdev);
dev_set_drvdata(dev, NULL);
return 0;
@ -987,9 +955,6 @@ static int __init axis_fifo_init(void)
{
pr_info("axis-fifo driver loaded with parameters read_timeout = %i, write_timeout = %i\n",
read_timeout, write_timeout);
axis_fifo_driver_class = class_create(THIS_MODULE, DRIVER_NAME);
if (IS_ERR(axis_fifo_driver_class))
return PTR_ERR(axis_fifo_driver_class);
return platform_driver_register(&axis_fifo_driver);
}
@ -998,7 +963,6 @@ module_init(axis_fifo_init);
static void __exit axis_fifo_exit(void)
{
platform_driver_unregister(&axis_fifo_driver);
class_destroy(axis_fifo_driver_class);
}
module_exit(axis_fifo_exit);