From: Beniamin Sandu <[email protected]>
Signed-off-by: Beniamin Sandu <[email protected]>
Signed-off-by: Ruiqiang Hao <[email protected]>
---
drivers/misc/rsmu_cdev.c | 185 +++++++++-----------------------------
drivers/misc/rsmu_cdev.h | 17 ++--
drivers/misc/rsmu_cm.c | 14 ++-
drivers/misc/rsmu_sabre.c | 8 +-
4 files changed, 62 insertions(+), 162 deletions(-)
diff --git a/drivers/misc/rsmu_cdev.c b/drivers/misc/rsmu_cdev.c
index c44fcebe3abb..0b1a15bb8d45 100644
--- a/drivers/misc/rsmu_cdev.c
+++ b/drivers/misc/rsmu_cdev.c
@@ -27,14 +27,13 @@
#include "rsmu_cdev.h"
-#define DRIVER_NAME "rsmu"
-#define DRIVER_MAX_DEV BIT(MINORBITS)
+#define DRIVER_NAME "rsmu-cdev"
+
+static DEFINE_IDA(rsmu_cdev_map);
-static struct class *rsmu_class;
-static dev_t rsmu_cdevt;
static struct rsmu_ops *ops_array[] = {
- [RSMU_CM] = &cm_ops,
- [RSMU_SABRE] = &sabre_ops,
+ [0] = &cm_ops,
+ [1] = &sabre_ops,
};
static int
@@ -115,11 +114,8 @@ rsmu_reg_read(struct rsmu_cdev *rsmu, void __user *arg)
return -EFAULT;
mutex_lock(rsmu->lock);
- //err = regmap_bulk_read(rsmu->regmap, data.offset, &data.bytes[0],
data.byte_count);
- err = rsmu_read(rsmu->mfd, data.offset, &data.bytes[0],
data.byte_count);
+ err = regmap_bulk_read(rsmu->regmap, data.offset, &data.bytes[0],
data.byte_count);
mutex_unlock(rsmu->lock);
- if (err)
- return err;
if (copy_to_user(arg, &data, sizeof(data)))
return -EFAULT;
@@ -136,55 +132,25 @@ rsmu_reg_write(struct rsmu_cdev *rsmu, void __user *arg)
if (copy_from_user(&data, arg, sizeof(data)))
return -EFAULT;
- mutex_lock(rsmu->lock);
- //err = regmap_bulk_write(rsmu->regmap, data.offset, &data.bytes[0],
data.byte_count);
- err = rsmu_write(rsmu->mfd, data.offset, &data.bytes[0], data.byte_count);
+ mutex_lock(rsmu->lock);
+ err = regmap_bulk_write(rsmu->regmap, data.offset, &data.bytes[0],
data.byte_count);
mutex_unlock(rsmu->lock);
- if (copy_to_user(arg, &data, sizeof(data)))
- return -EFAULT;
-
return err;
}
-
-static int
-rsmu_open(struct inode *iptr, struct file *fptr)
-{
- struct rsmu_cdev *rsmu;
-
- rsmu = container_of(iptr->i_cdev, struct rsmu_cdev, rsmu_cdev);
- if (!rsmu)
- return -EAGAIN;
-
- fptr->private_data = rsmu;
- return 0;
-}
-
-static int
-rsmu_release(struct inode *iptr, struct file *fptr)
+static struct rsmu_cdev *file2rsmu(struct file *file)
{
- struct rsmu_cdev *rsmu;
-
- rsmu = container_of(iptr->i_cdev, struct rsmu_cdev, rsmu_cdev);
- if (!rsmu)
- return -EAGAIN;
-
- return 0;
+ return container_of(file->private_data, struct rsmu_cdev, miscdev);
}
-
-
static long
rsmu_ioctl(struct file *fptr, unsigned int cmd, unsigned long data)
{
- struct rsmu_cdev *rsmu = fptr->private_data;
+ struct rsmu_cdev *rsmu = file2rsmu(fptr);
void __user *arg = (void __user *)data;
int err = 0;
- if (!rsmu)
- return -EINVAL;
-
switch (cmd) {
case RSMU_SET_COMBOMODE:
err = rsmu_set_combomode(rsmu, arg);
@@ -203,7 +169,6 @@ rsmu_ioctl(struct file *fptr, unsigned int cmd, unsigned
long data)
break;
default:
/* Should not get here */
- pr_err("%lu %u", RSMU_REG_READ, cmd);
dev_err(rsmu->dev, "Undefined RSMU IOCTL");
err = -EINVAL;
break;
@@ -220,8 +185,6 @@ static long rsmu_compat_ioctl(struct file *fptr, unsigned
int cmd,
static const struct file_operations rsmu_fops = {
.owner = THIS_MODULE,
- .open = rsmu_open,
- .release = rsmu_release,
.unlocked_ioctl = rsmu_ioctl,
.compat_ioctl = rsmu_compat_ioctl,
};
@@ -244,90 +207,65 @@ static int rsmu_init_ops(struct rsmu_cdev *rsmu)
static int
rsmu_probe(struct platform_device *pdev)
{
- struct rsmu_pdata *pdata = dev_get_platdata(&pdev->dev);
+ struct rsmu_ddata *ddata = dev_get_drvdata(pdev->dev.parent);
struct rsmu_cdev *rsmu;
- struct device *rsmu_cdev;
int err;
rsmu = devm_kzalloc(&pdev->dev, sizeof(*rsmu), GFP_KERNEL);
if (!rsmu)
return -ENOMEM;
- rsmu->dev = &pdev->dev;
- rsmu->mfd = pdev->dev.parent;
- rsmu->type = pdata->type;
- rsmu->lock = pdata->lock;
- rsmu->index = pdata->index;
-
/* Save driver private data */
platform_set_drvdata(pdev, rsmu);
- cdev_init(&rsmu->rsmu_cdev, &rsmu_fops);
- rsmu->rsmu_cdev.owner = THIS_MODULE;
- err = cdev_add(&rsmu->rsmu_cdev,
- MKDEV(MAJOR(rsmu_cdevt), 0), 1);
- if (err < 0) {
- dev_err(rsmu->dev, "cdev_add failed");
- err = -EIO;
- goto err_rsmu_dev;
- }
-
- if (!rsmu_class) {
- err = -EIO;
- dev_err(rsmu->dev, "rsmu class not created correctly");
- goto err_rsmu_cdev;
+ rsmu->dev = &pdev->dev;
+ rsmu->mfd = pdev->dev.parent;
+ rsmu->type = ddata->type;
+ rsmu->lock = &ddata->lock;
+ rsmu->regmap = ddata->regmap;
+ rsmu->index = ida_simple_get(&rsmu_cdev_map, 0, MINORMASK + 1,
GFP_KERNEL);
+ if (rsmu->index < 0) {
+ dev_err(rsmu->dev, "Unable to get index %d\n", rsmu->index);
+ return rsmu->index;
}
+ snprintf(rsmu->name, sizeof(rsmu->name), "rsmu%d", rsmu->index);
- rsmu_cdev = device_create(rsmu_class, rsmu->dev,
- MKDEV(MAJOR(rsmu_cdevt), 0),
- rsmu, "rsmu%d", rsmu->index);
- if (IS_ERR(rsmu_cdev)) {
- dev_err(rsmu->dev, "Unable to create char device");
- err = PTR_ERR(rsmu_cdev);
- goto err_rsmu_cdev;
+ err = rsmu_init_ops(rsmu);
+ if (err) {
+ dev_err(rsmu->dev, "Unknown SMU type %d", rsmu->type);
+ ida_simple_remove(&rsmu_cdev_map, rsmu->index);
+ return err;
}
- err = rsmu_init_ops(rsmu);
+ /* Initialize and register the miscdev */
+ rsmu->miscdev.minor = MISC_DYNAMIC_MINOR;
+ rsmu->miscdev.fops = &rsmu_fops;
+ rsmu->miscdev.name = rsmu->name;
+ err = misc_register(&rsmu->miscdev);
if (err) {
- dev_err(rsmu->dev, "Unable to match type %d", rsmu->type);
- goto err_rsmu_cdev;
+ dev_err(rsmu->dev, "Unable to register device\n");
+ ida_simple_remove(&rsmu_cdev_map, rsmu->index);
+ return -ENODEV;
}
- dev_info(rsmu->dev, "Probe SMU type %d successful\n", rsmu->type);
+ dev_info(rsmu->dev, "Probe %s successful\n", rsmu->name);
return 0;
-
- /* Failure cleanup */
-err_rsmu_cdev:
- cdev_del(&rsmu->rsmu_cdev);
-err_rsmu_dev:
- return err;
}
static int
rsmu_remove(struct platform_device *pdev)
{
struct rsmu_cdev *rsmu = platform_get_drvdata(pdev);
- struct device *dev = &pdev->dev;
-
- if (!rsmu)
- return -ENODEV;
- if (!rsmu_class) {
- dev_err(dev, "rsmu_class is NULL");
- return -EIO;
- }
-
- device_destroy(rsmu_class, MKDEV(MAJOR(rsmu_cdevt), 0));
- cdev_del(&rsmu->rsmu_cdev);
+ misc_deregister(&rsmu->miscdev);
+ ida_simple_remove(&rsmu_cdev_map, rsmu->index);
return 0;
}
static const struct platform_device_id rsmu_id_table[] = {
- { "rsmu-cdev0", },
- { "rsmu-cdev1", },
- { "rsmu-cdev2", },
- { "rsmu-cdev3", },
+ { "8a3400x-cdev", RSMU_CM},
+ { "82p33x1x-cdev", RSMU_SABRE},
{}
};
MODULE_DEVICE_TABLE(platform, rsmu_id_table);
@@ -341,48 +279,7 @@ static struct platform_driver rsmu_driver = {
.id_table = rsmu_id_table,
};
-static int __init rsmu_init(void)
-{
- int err;
-
- rsmu_class = class_create(THIS_MODULE, DRIVER_NAME);
- if (IS_ERR(rsmu_class)) {
- err = PTR_ERR(rsmu_class);
- pr_err("Unable to register rsmu class");
- return err;
- }
-
- err = alloc_chrdev_region(&rsmu_cdevt, 0, DRIVER_MAX_DEV, DRIVER_NAME);
- if (err < 0) {
- pr_err("Unable to get major number");
- goto err_rsmu_class;
- }
-
- err = platform_driver_register(&rsmu_driver);
- if (err < 0) {
- pr_err("Unabled to register %s driver", DRIVER_NAME);
- goto err_rsmu_drv;
- }
- return 0;
-
- /* Error Path */
-err_rsmu_drv:
- unregister_chrdev_region(rsmu_cdevt, DRIVER_MAX_DEV);
-err_rsmu_class:
- class_destroy(rsmu_class);
- return err;
-}
-
-static void __exit rsmu_exit(void)
-{
- platform_driver_unregister(&rsmu_driver);
- unregister_chrdev_region(rsmu_cdevt, DRIVER_MAX_DEV);
- class_destroy(rsmu_class);
- rsmu_class = NULL;
-}
-
-module_init(rsmu_init);
-module_exit(rsmu_exit);
+module_platform_driver(rsmu_driver);
MODULE_DESCRIPTION("Renesas SMU character device driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/misc/rsmu_cdev.h b/drivers/misc/rsmu_cdev.h
index 3ced817ce3df..d67f71a668be 100644
--- a/drivers/misc/rsmu_cdev.h
+++ b/drivers/misc/rsmu_cdev.h
@@ -8,28 +8,33 @@
#ifndef __LINUX_RSMU_CDEV_H
#define __LINUX_RSMU_CDEV_H
-#include <linux/cdev.h>
+#include <linux/miscdevice.h>
+#include <linux/regmap.h>
struct rsmu_ops;
/**
* struct rsmu_cdev - Driver data for RSMU character device
- * @dev: pointer to platform device
+ * @name: rsmu device name as rsmu[index]
+ * @dev: pointer to device
* @mfd: pointer to MFD device
- * @rsmu_cdev: character device handle
+ * @miscdev: character device handle
+ * @regmap: I2C/SPI regmap handle
* @lock: mutex to protect operations from being interrupted
- * @type: rsmu device type
+ * @type: rsmu device type, passed through platform data
* @ops: rsmu device methods
* @index: rsmu device index
*/
struct rsmu_cdev {
+ char name[16];
struct device *dev;
struct device *mfd;
- struct cdev rsmu_cdev;
+ struct miscdevice miscdev;
+ struct regmap *regmap;
struct mutex *lock;
enum rsmu_type type;
struct rsmu_ops *ops;
- u8 index;
+ int index;
};
extern struct rsmu_ops cm_ops;
diff --git a/drivers/misc/rsmu_cm.c b/drivers/misc/rsmu_cm.c
index d5af624badff..d1f2d7ae6e23 100644
--- a/drivers/misc/rsmu_cm.c
+++ b/drivers/misc/rsmu_cm.c
@@ -53,8 +53,8 @@ static int rsmu_cm_set_combomode(struct rsmu_cdev *rsmu, u8
dpll, u8 mode)
if (mode >= E_COMBOMODE_MAX)
return -EINVAL;
- err = rsmu_read(rsmu->mfd, dpll_ctrl_n + DPLL_CTRL_COMBO_MASTER_CFG,
- &cfg, sizeof(cfg));
+ err = regmap_bulk_read(rsmu->regmap, dpll_ctrl_n +
DPLL_CTRL_COMBO_MASTER_CFG,
+ &cfg, sizeof(cfg));
if (err)
return err;
@@ -64,8 +64,8 @@ static int rsmu_cm_set_combomode(struct rsmu_cdev *rsmu, u8
dpll, u8 mode)
else
cfg &= ~COMBO_MASTER_HOLD;
- return rsmu_write(rsmu->mfd, dpll_ctrl_n + DPLL_CTRL_COMBO_MASTER_CFG,
- &cfg, sizeof(cfg));
+ return regmap_bulk_write(rsmu->regmap, dpll_ctrl_n +
DPLL_CTRL_COMBO_MASTER_CFG,
+ &cfg, sizeof(cfg));
}
static int rsmu_cm_get_dpll_state(struct rsmu_cdev *rsmu, u8 dpll, u8 *state)
@@ -77,9 +77,7 @@ static int rsmu_cm_get_dpll_state(struct rsmu_cdev *rsmu, u8
dpll, u8 *state)
if (dpll > 8)
return -EINVAL;
- err = rsmu_read(rsmu->mfd,
- STATUS + DPLL0_STATUS + dpll,
- &cfg, sizeof(cfg));
+ err = regmap_bulk_read(rsmu->regmap, STATUS + DPLL0_STATUS + dpll,
&cfg, sizeof(cfg));
if (err)
return err;
@@ -145,7 +143,7 @@ static int rsmu_cm_get_dpll_ffo(struct rsmu_cdev *rsmu, u8
dpll,
return -EINVAL;
}
- err = rsmu_read(rsmu->mfd, STATUS + dpll_filter_status, buf, 6);
+ err = regmap_bulk_read(rsmu->regmap, STATUS + dpll_filter_status, buf,
6);
if (err)
return err;
diff --git a/drivers/misc/rsmu_sabre.c b/drivers/misc/rsmu_sabre.c
index aa772f1c0854..fd9853c7cfb7 100644
--- a/drivers/misc/rsmu_sabre.c
+++ b/drivers/misc/rsmu_sabre.c
@@ -35,14 +35,14 @@ static int rsmu_sabre_set_combomode(struct rsmu_cdev *rsmu,
u8 dpll, u8 mode)
if (mode >= E_COMBOMODE_MAX)
return -EINVAL;
- err = rsmu_read(rsmu->mfd, dpll_ctrl_n, &cfg, sizeof(cfg));
+ err = regmap_bulk_read(rsmu->regmap, dpll_ctrl_n, &cfg, sizeof(cfg));
if (err)
return err;
cfg &= ~(COMBO_MODE_MASK << COMBO_MODE_SHIFT);
cfg |= mode << COMBO_MODE_SHIFT;
- return rsmu_write(rsmu->mfd, dpll_ctrl_n, &cfg, sizeof(cfg));
+ return regmap_bulk_write(rsmu->regmap, dpll_ctrl_n, &cfg, sizeof(cfg));
}
static int rsmu_sabre_get_dpll_state(struct rsmu_cdev *rsmu, u8 dpll, u8
*state)
@@ -62,7 +62,7 @@ static int rsmu_sabre_get_dpll_state(struct rsmu_cdev *rsmu,
u8 dpll, u8 *state)
return -EINVAL;
}
- err = rsmu_read(rsmu->mfd, dpll_sts_n, &cfg, sizeof(cfg));
+ err = regmap_bulk_read(rsmu->regmap, dpll_sts_n, &cfg, sizeof(cfg));
if (err)
return err;
@@ -107,7 +107,7 @@ static int rsmu_sabre_get_dpll_ffo(struct rsmu_cdev *rsmu,
u8 dpll,
return -EINVAL;
}
- err = rsmu_read(rsmu->mfd, dpll_freq_n, buf, 5);
+ err = regmap_bulk_read(rsmu->regmap, dpll_freq_n, buf, 5);
if (err)
return err;
--
2.25.1
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#11850):
https://lists.yoctoproject.org/g/linux-yocto/message/11850
Mute This Topic: https://lists.yoctoproject.org/mt/94862181/21656
Group Owner: [email protected]
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-