mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-08 15:04:45 +00:00
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:
parent
dfd1a05a38
commit
d2d7aa5389
@ -30,6 +30,7 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
|
#include <linux/miscdevice.h>
|
||||||
|
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
@ -102,9 +103,6 @@
|
|||||||
* globals
|
* 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 read_timeout = 1000; /* ms to wait before read() times out */
|
||||||
static int write_timeout = 1000; /* ms to wait before write() 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 */
|
unsigned int read_flags; /* read file flags */
|
||||||
|
|
||||||
struct device *dt_device; /* device created from the device tree */
|
struct device *dt_device; /* device created from the device tree */
|
||||||
struct device *device; /* device associated with char_device */
|
struct miscdevice miscdev;
|
||||||
dev_t devt; /* our char device number */
|
|
||||||
struct cdev char_device; /* our char device */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------------------
|
/* ----------------------------
|
||||||
@ -319,6 +315,11 @@ static const struct attribute_group axis_fifo_attrs_group = {
|
|||||||
.attrs = axis_fifo_attrs,
|
.attrs = axis_fifo_attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group *axis_fifo_attrs_groups[] = {
|
||||||
|
&axis_fifo_attrs_group,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
/* ----------------------------
|
/* ----------------------------
|
||||||
* implementation
|
* 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)
|
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 *fifo = container_of(f->private_data,
|
||||||
struct axis_fifo, char_device);
|
struct axis_fifo, miscdev);
|
||||||
f->private_data = fifo;
|
f->private_data = fifo;
|
||||||
|
|
||||||
if (((f->f_flags & O_ACCMODE) == O_WRONLY) ||
|
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 resource *r_mem; /* IO mem resources */
|
||||||
struct device *dev = &pdev->dev; /* OS device (from device tree) */
|
struct device *dev = &pdev->dev; /* OS device (from device tree) */
|
||||||
struct axis_fifo *fifo = NULL;
|
struct axis_fifo *fifo = NULL;
|
||||||
|
char *device_name;
|
||||||
char device_name[32];
|
|
||||||
|
|
||||||
int rc = 0; /* error return value */
|
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 */
|
/* allocate device wrapper memory */
|
||||||
fifo = devm_kmalloc(dev, sizeof(*fifo), GFP_KERNEL);
|
fifo = devm_kzalloc(dev, sizeof(*fifo), GFP_KERNEL);
|
||||||
if (!fifo)
|
if (!fifo)
|
||||||
return -ENOMEM;
|
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);
|
dev_dbg(fifo->dt_device, "remapped memory to 0x%p\n", fifo->base_addr);
|
||||||
|
|
||||||
/* create unique device name */
|
/* create unique device name */
|
||||||
snprintf(device_name, sizeof(device_name), "%s_%pa",
|
snprintf(device_name, 32, "%s_%pa", DRIVER_NAME, &r_mem->start);
|
||||||
DRIVER_NAME, &r_mem->start);
|
|
||||||
|
|
||||||
dev_dbg(fifo->dt_device, "device name [%s]\n", device_name);
|
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 */
|
/* create character device */
|
||||||
rc = alloc_chrdev_region(&fifo->devt, 0, 1, DRIVER_NAME);
|
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)
|
if (rc < 0)
|
||||||
goto err_initial;
|
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 */
|
dev_info(fifo->dt_device, "axis-fifo created at %pa mapped to 0x%pa, irq=%i\n",
|
||||||
fifo->device = device_create(axis_fifo_driver_class, NULL, fifo->devt,
|
&r_mem->start, &fifo->base_addr, fifo->irq);
|
||||||
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));
|
|
||||||
|
|
||||||
return 0;
|
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:
|
err_initial:
|
||||||
dev_set_drvdata(dev, NULL);
|
dev_set_drvdata(dev, NULL);
|
||||||
return rc;
|
return rc;
|
||||||
@ -959,10 +930,7 @@ static int axis_fifo_remove(struct platform_device *pdev)
|
|||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct axis_fifo *fifo = dev_get_drvdata(dev);
|
struct axis_fifo *fifo = dev_get_drvdata(dev);
|
||||||
|
|
||||||
cdev_del(&fifo->char_device);
|
misc_deregister(&fifo->miscdev);
|
||||||
dev_set_drvdata(fifo->device, NULL);
|
|
||||||
device_destroy(axis_fifo_driver_class, fifo->devt);
|
|
||||||
unregister_chrdev_region(fifo->devt, 1);
|
|
||||||
dev_set_drvdata(dev, NULL);
|
dev_set_drvdata(dev, NULL);
|
||||||
|
|
||||||
return 0;
|
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",
|
pr_info("axis-fifo driver loaded with parameters read_timeout = %i, write_timeout = %i\n",
|
||||||
read_timeout, write_timeout);
|
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);
|
return platform_driver_register(&axis_fifo_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -998,7 +963,6 @@ module_init(axis_fifo_init);
|
|||||||
static void __exit axis_fifo_exit(void)
|
static void __exit axis_fifo_exit(void)
|
||||||
{
|
{
|
||||||
platform_driver_unregister(&axis_fifo_driver);
|
platform_driver_unregister(&axis_fifo_driver);
|
||||||
class_destroy(axis_fifo_driver_class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_exit(axis_fifo_exit);
|
module_exit(axis_fifo_exit);
|
||||||
|
Loading…
Reference in New Issue
Block a user