On Wed, 12 Jan 2022 at 23:12, Jay Chen jkchen@linux.alibaba.com wrote:
Currently, there are 130 etr and etf on our machine, but the current coresight tmc driver uses misc_register to register the device, which leads to the error that the device number is not enough.
coresight-tmc: probe of xxxxx failed with error -16
This patch changes the device registration method to cdev's dynamic registration method to solve the problem of insufficient device numbers.
On December 21st you posted this patch with a "RFC V3 PATCH" tag. On January 5th you posted a new version with a simple "PATCH" tag which, minutes later, was superseded by another patch labelled "RESEND PATCH". Today you're sending yet another revision labelled "RESEND PATCH V2"...
Is it a "V2" of the "RESEND PATCH" that was a new revision of the "RFC V3 PATCH"? Are you confused? I certainly am...
Signed-off-by: Jay Chen jkchen@linux.alibaba.com
.../hwtracing/coresight/coresight-tmc-core.c | 103 ++++++++++++++---- drivers/hwtracing/coresight/coresight-tmc.h | 11 +- 2 files changed, 91 insertions(+), 23 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index d0276af82494..0977f1ce6338 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -12,7 +12,6 @@ #include <linux/io.h> #include <linux/err.h> #include <linux/fs.h> -#include <linux/miscdevice.h> #include <linux/mutex.h> #include <linux/property.h> #include <linux/uaccess.h> @@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb"); DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf"); DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
+static DEFINE_IDA(tmc_ida); +static dev_t tmc_major; +static struct class *tmc_class;
+#define TMC_DEV_MAX (MINORMASK + 1)
void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata) { struct coresight_device *csdev = drvdata->csdev; @@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata) static int tmc_open(struct inode *inode, struct file *file) { int ret;
struct tmc_drvdata *drvdata = container_of(file->private_data,
struct tmc_drvdata, miscdev);
struct tmc_cdev *cdev = container_of(inode->i_cdev,
struct tmc_cdev, cdev);
struct tmc_drvdata *drvdata = container_of(cdev,
struct tmc_drvdata, cdev); ret = tmc_read_prepare(drvdata); if (ret)
@@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len, { char *bufp; ssize_t actual;
struct tmc_drvdata *drvdata = container_of(file->private_data,
struct tmc_drvdata, miscdev);
struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
struct tmc_cdev, cdev);
struct tmc_drvdata *drvdata = container_of(cdev,
struct tmc_drvdata, cdev); actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp); if (actual <= 0) return 0;
@@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len, static int tmc_release(struct inode *inode, struct file *file) { int ret;
struct tmc_drvdata *drvdata = container_of(file->private_data,
struct tmc_drvdata, miscdev);
struct tmc_cdev *cdev = container_of(inode->i_cdev,
struct tmc_cdev, cdev);
struct tmc_drvdata *drvdata = container_of(cdev,
struct tmc_drvdata, cdev); ret = tmc_read_unprepare(drvdata); if (ret)
@@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) { int ret = 0; u32 devid;
dev_t devt; void __iomem *base; struct device *dev = &adev->dev; struct coresight_platform_data *pdata = NULL;
@@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) goto out; }
drvdata->miscdev.name = desc.name;
drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
drvdata->miscdev.fops = &tmc_fops;
ret = misc_register(&drvdata->miscdev);
ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
if (ret < 0)
goto err_coresight_unregister;
cdev_init(&drvdata->cdev.cdev, &tmc_fops);
drvdata->cdev.cdev.owner = THIS_MODULE;
devt = MKDEV(MAJOR(tmc_major), ret);
ret = cdev_add(&drvdata->cdev.cdev, devt, 1); if (ret)
coresight_unregister(drvdata->csdev);
else
goto err_free_tmc_ida;
drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
if (IS_ERR(drvdata->cdev.dev)) {
ret = PTR_ERR(drvdata->cdev.dev);
goto err_delete_cdev;
} else pm_runtime_put(&adev->dev);
return 0;
+err_delete_cdev:
cdev_del(&drvdata->cdev.cdev);
+err_free_tmc_ida:
ida_simple_remove(&tmc_ida, MINOR(devt));
+err_coresight_unregister:
coresight_unregister(drvdata->csdev);
out: return ret; } @@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev) static void tmc_remove(struct amba_device *adev) { struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
struct device *dev = drvdata->cdev.dev;
/*
* Since misc_open() holds a refcount on the f_ops, which is
* etb fops in this case, device is there until last file
* handler to this device is closed.
*/
misc_deregister(&drvdata->miscdev);
ida_simple_remove(&tmc_ida, MINOR(dev->devt));
device_destroy(tmc_class, dev->devt);
cdev_del(&drvdata->cdev.cdev); coresight_unregister(drvdata->csdev);
}
@@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = { .id_table = tmc_ids, };
-module_amba_driver(tmc_driver); +static int __init tmc_init(void) +{
int ret;
ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
if (ret < 0) {
pr_err("tmc: failed to allocate char dev region\n");
return ret;
}
tmc_class = class_create(THIS_MODULE, "tmc");
if (IS_ERR(tmc_class)) {
pr_err("tmc: failed to create class\n");
unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
return PTR_ERR(tmc_class);
}
ret = amba_driver_register(&tmc_driver);
if (ret) {
pr_err("tmc: error registering amba driver\n");
class_destroy(tmc_class);
unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
}
return ret;
+}
+static void __exit tmc_exit(void) +{
amba_driver_unregister(&tmc_driver);
class_destroy(tmc_class);
unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+}
+module_init(tmc_init); +module_exit(tmc_exit);
MODULE_AUTHOR("Pratik Patel pratikp@codeaurora.org"); MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver"); diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 6bec20a392b3..11441c6b9c26 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -7,9 +7,9 @@ #ifndef _CORESIGHT_TMC_H #define _CORESIGHT_TMC_H
+#include <linux/cdev.h> #include <linux/dma-mapping.h> #include <linux/idr.h> -#include <linux/miscdevice.h> #include <linux/mutex.h> #include <linux/refcount.h>
@@ -163,11 +163,16 @@ struct etr_buf { void *private; };
+struct tmc_cdev {
struct cdev cdev;
struct device *dev;
+};
/**
- struct tmc_drvdata - specifics associated to an TMC component
- @base: memory mapped base address for this component.
- @csdev: component vitals needed by the framework.
- @miscdev: specifics to handle "/dev/xyz.tmc" entry.
- @tmc_cdev: specifics to handle "/dev/xyz.tmc" entry.
- @spinlock: only one at a time pls.
- @pid: Process ID of the process being monitored by the session
that is using this component.
@@ -191,7 +196,7 @@ struct etr_buf { struct tmc_drvdata { void __iomem *base; struct coresight_device *csdev;
struct miscdevice miscdev;
struct tmc_cdev cdev; spinlock_t spinlock; pid_t pid; bool reading;
-- 2.27.0