From: Beniamin Sandu <beniamin.sa...@windriver.com> Signed-off-by: Beniamin Sandu <beniamin.sa...@windriver.com> Signed-off-by: Ruiqiang Hao <ruiqiang....@windriver.com> --- 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: linux-yocto+ow...@lists.yoctoproject.org Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-