diff options
author | Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> | 2011-09-07 12:28:30 +0200 |
---|---|---|
committer | Jonas ABERG <jonas.aberg@stericsson.com> | 2011-09-29 09:07:17 +0200 |
commit | 69aea9a09b41410c04564a23d59da09267192da3 (patch) | |
tree | ff0f77c4f4eaee035890f5166c2ecc027fff84ec /drivers | |
parent | 73708744a98d7627586aa1a522fb5b1b59de4cdb (diff) |
ux500: regulator: add debugging support for dbx500 regulators
ST-Ericsson ID: 360515
ST-Ericsson Linux next: NA
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: I71dbb5bc63e08998486a7c3a699a4d90da59df4e
Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32137
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Tested-by: Jonas ABERG <jonas.aberg@stericsson.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/db5500-prcmu.c | 53 | ||||
-rw-r--r-- | drivers/regulator/db8500-prcmu.c | 59 | ||||
-rw-r--r-- | drivers/regulator/dbx500-prcmu.c | 134 | ||||
-rw-r--r-- | drivers/regulator/dbx500-prcmu.h | 39 |
4 files changed, 210 insertions, 75 deletions
diff --git a/drivers/regulator/db5500-prcmu.c b/drivers/regulator/db5500-prcmu.c index d52f459fc3c..60e725b2250 100644 --- a/drivers/regulator/db5500-prcmu.c +++ b/drivers/regulator/db5500-prcmu.c @@ -19,31 +19,10 @@ #include <mach/prcmu.h> -/** - * struct db5500_regulator_info - db5500 regulator information - * @dev: device pointer - * @desc: regulator description - * @rdev: regulator device pointer - * @is_enabled: status of the regulator - * @epod_id: id for EPOD (power domain) - * @is_ramret: RAM retention switch for EPOD (power domain) - * @operating_point: operating point (only for vape, to be removed) - * - */ -struct db5500_regulator_info { - struct device *dev; - struct regulator_desc desc; - struct regulator_dev *rdev; - bool is_enabled; - u16 epod_id; - bool is_ramret; - bool exclude_from_power_state; - unsigned int operating_point; -}; - +#include "dbx500-prcmu.h" static int db5500_regulator_enable(struct regulator_dev *rdev) { - struct db5500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -60,7 +39,7 @@ static int db5500_regulator_enable(struct regulator_dev *rdev) static int db5500_regulator_disable(struct regulator_dev *rdev) { - struct db5500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret = 0; if (info == NULL) @@ -78,7 +57,7 @@ static int db5500_regulator_disable(struct regulator_dev *rdev) static int db5500_regulator_is_enabled(struct regulator_dev *rdev) { - struct db5500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -162,7 +141,7 @@ static int disable_epod(u16 epod_id, bool ramret) */ static int db5500_regulator_switch_enable(struct regulator_dev *rdev) { - struct db5500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret; if (info == NULL) @@ -186,7 +165,7 @@ out: static int db5500_regulator_switch_disable(struct regulator_dev *rdev) { - struct db5500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret; if (info == NULL) @@ -210,7 +189,7 @@ out: static int db5500_regulator_switch_is_enabled(struct regulator_dev *rdev) { - struct db5500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -243,8 +222,8 @@ static struct regulator_ops db5500_regulator_switch_ops = { .epod_id = DB5500_EPOD_ID_##reg, \ } -static struct db5500_regulator_info - db5500_regulator_info[DB5500_NUM_REGULATORS] = { +static struct dbx500_regulator_info + dbx500_regulator_info[DB5500_NUM_REGULATORS] = { [DB5500_REGULATOR_VAPE] = { .desc = { .name = "db5500-vape", @@ -268,12 +247,12 @@ static int __devinit db5500_regulator_probe(struct platform_device *pdev) int i, err; /* register all regulators */ - for (i = 0; i < ARRAY_SIZE(db5500_regulator_info); i++) { - struct db5500_regulator_info *info; + for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { + struct dbx500_regulator_info *info; struct regulator_init_data *init_data = &db5500_init_data[i]; /* assign per-regulator data */ - info = &db5500_regulator_info[i]; + info = &dbx500_regulator_info[i]; info->dev = &pdev->dev; /* register with the regulator framework */ @@ -287,7 +266,7 @@ static int __devinit db5500_regulator_probe(struct platform_device *pdev) /* if failing, unregister all earlier regulators */ i--; while (i >= 0) { - info = &db5500_regulator_info[i]; + info = &dbx500_regulator_info[i]; regulator_unregister(info->rdev); i--; } @@ -305,9 +284,9 @@ static int __exit db5500_regulator_remove(struct platform_device *pdev) { int i; - for (i = 0; i < ARRAY_SIZE(db5500_regulator_info); i++) { - struct db5500_regulator_info *info; - info = &db5500_regulator_info[i]; + for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { + struct dbx500_regulator_info *info; + info = &dbx500_regulator_info[i]; dev_vdbg(rdev_get_dev(info->rdev), "regulator-%s-remove\n", info->desc.name); diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index a6156496fde..65e2f83db33 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -19,31 +19,9 @@ #include <linux/regulator/db8500-prcmu.h> #include "dbx500-prcmu.h" -/** - * struct db8500_regulator_info - db8500 regulator information - * @dev: device pointer - * @desc: regulator description - * @rdev: regulator device pointer - * @is_enabled: status of the regulator - * @epod_id: id for EPOD (power domain) - * @is_ramret: RAM retention switch for EPOD (power domain) - * @operating_point: operating point (only for vape, to be removed) - * - */ -struct db8500_regulator_info { - struct device *dev; - struct regulator_desc desc; - struct regulator_dev *rdev; - bool is_enabled; - u16 epod_id; - bool is_ramret; - bool exclude_from_power_state; - unsigned int operating_point; -}; - static int db8500_regulator_enable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -60,7 +38,7 @@ static int db8500_regulator_enable(struct regulator_dev *rdev) static int db8500_regulator_disable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret = 0; if (info == NULL) @@ -78,7 +56,7 @@ static int db8500_regulator_disable(struct regulator_dev *rdev) static int db8500_regulator_is_enabled(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -155,7 +133,7 @@ static int disable_epod(u16 epod_id, bool ramret) */ static int db8500_regulator_switch_enable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret; if (info == NULL) @@ -179,7 +157,7 @@ out: static int db8500_regulator_switch_disable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret; if (info == NULL) @@ -203,7 +181,7 @@ out: static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -224,8 +202,8 @@ static struct regulator_ops db8500_regulator_switch_ops = { /* * Regulator information */ -static struct db8500_regulator_info -db8500_regulator_info[DB8500_NUM_REGULATORS] = { +static struct dbx500_regulator_info +dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VAPE] = { .desc = { .name = "db8500-vape", @@ -434,12 +412,12 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) int i, err; /* register all regulators */ - for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { - struct db8500_regulator_info *info; + for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { + struct dbx500_regulator_info *info; struct regulator_init_data *init_data = &db8500_init_data[i]; /* assign per-regulator data */ - info = &db8500_regulator_info[i]; + info = &dbx500_regulator_info[i]; info->dev = &pdev->dev; /* register with the regulator framework */ @@ -452,7 +430,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) /* if failing, unregister all earlier regulators */ while (--i >= 0) { - info = &db8500_regulator_info[i]; + info = &dbx500_regulator_info[i]; regulator_unregister(info->rdev); } return err; @@ -461,17 +439,22 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) dev_dbg(rdev_get_dev(info->rdev), "regulator-%s-probed\n", info->desc.name); } + err = ux500_regulator_debug_init(pdev, + dbx500_regulator_info, + ARRAY_SIZE(dbx500_regulator_info)); - return 0; + return err; } static int __exit db8500_regulator_remove(struct platform_device *pdev) { int i; - for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { - struct db8500_regulator_info *info; - info = &db8500_regulator_info[i]; + ux500_regulator_debug_exit(); + + for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { + struct dbx500_regulator_info *info; + info = &dbx500_regulator_info[i]; dev_vdbg(rdev_get_dev(info->rdev), "regulator-%s-remove\n", info->desc.name); diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index 3bc6e0e5189..fb6976ee7d2 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c @@ -11,6 +11,10 @@ #include <linux/kernel.h> #include <linux/err.h> #include <linux/regulator/driver.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/slab.h> + #include "dbx500-prcmu.h" /* @@ -145,3 +149,133 @@ void ux500_regulator_put(struct ux500_regulator *regulator) /* Here for symetric reasons and for possible future use */ } EXPORT_SYMBOL_GPL(ux500_regulator_put); + +#ifdef CONFIG_REGULATOR_DEBUG + +static struct ux500_regulator_debug { + struct dentry *dir; + struct dentry *status_file; + struct dbx500_regulator_info *regulator_array; + int num_regulators; + u8 *state_before_suspend; + u8 *state_after_suspend; +} rdebug; + +void ux500_regulator_suspend_debug(void) +{ + int i; + for (i = 0; i < rdebug.num_regulators; i++) + rdebug.state_before_suspend[i] = + rdebug.regulator_array[i].is_enabled; +} + +void ux500_regulator_resume_debug(void) +{ + int i; + for (i = 0; i < rdebug.num_regulators; i++) + rdebug.state_after_suspend[i] = + rdebug.regulator_array[i].is_enabled; +} + +static int ux500_regulator_status_print(struct seq_file *s, void *p) +{ + struct device *dev = s->private; + int err; + int i; + + /* print dump header */ + err = seq_printf(s, "ux500-regulator status:\n"); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + + err = seq_printf(s, "%31s : %8s : %8s\n", "current", + "before", "after"); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + + for (i = 0; i < rdebug.num_regulators; i++) { + struct dbx500_regulator_info *info; + /* Access per-regulator data */ + info = &rdebug.regulator_array[i]; + + /* print status */ + err = seq_printf(s, "%20s : %8s : %8s : %8s\n", info->desc.name, + info->is_enabled ? "enabled" : "disabled", + rdebug.state_before_suspend[i] ? "enabled" : "disabled", + rdebug.state_after_suspend[i] ? "enabled" : "disabled"); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + } + + return 0; +} + +static int ux500_regulator_status_open(struct inode *inode, struct file *file) +{ + return single_open(file, ux500_regulator_status_print, + inode->i_private); +} + +static const struct file_operations ux500_regulator_status_fops = { + .open = ux500_regulator_status_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +int __devinit +ux500_regulator_debug_init(struct platform_device *pdev, + struct dbx500_regulator_info *regulator_info, + int num_regulators) +{ + /* create directory */ + rdebug.dir = debugfs_create_dir("ux500-regulator", NULL); + if (!rdebug.dir) + goto exit_no_debugfs; + + /* create "status" file */ + rdebug.status_file = debugfs_create_file("status", + S_IRUGO, rdebug.dir, &pdev->dev, + &ux500_regulator_status_fops); + if (!rdebug.status_file) + goto exit_destroy_dir; + + rdebug.regulator_array = regulator_info; + rdebug.num_regulators = num_regulators; + + rdebug.state_before_suspend = kzalloc(num_regulators, GFP_KERNEL); + if (!rdebug.state_before_suspend) { + dev_err(&pdev->dev, + "could not allocate memory for saving state\n"); + goto exit_destory_status; + } + + rdebug.state_after_suspend = kzalloc(num_regulators, GFP_KERNEL); + if (!rdebug.state_after_suspend) { + dev_err(&pdev->dev, + "could not allocate memory for saving state\n"); + goto exit_free; + } + return 0; + +exit_free: + kfree(rdebug.state_before_suspend); +exit_destory_status: + debugfs_remove(rdebug.status_file); +exit_destroy_dir: + debugfs_remove(rdebug.dir); +exit_no_debugfs: + dev_err(&pdev->dev, "failed to create debugfs entries.\n"); + return -ENOMEM; +} + +int __devexit ux500_regulator_debug_exit(void) +{ + debugfs_remove_recursive(rdebug.dir); + kfree(rdebug.state_after_suspend); + kfree(rdebug.state_before_suspend); + + return 0; +} +#endif diff --git a/drivers/regulator/dbx500-prcmu.h b/drivers/regulator/dbx500-prcmu.h index bc6191943b1..f7e20fe075a 100644 --- a/drivers/regulator/dbx500-prcmu.h +++ b/drivers/regulator/dbx500-prcmu.h @@ -11,7 +11,46 @@ #ifndef DBX500_REGULATOR_H #define DBX500_REGULATOR_H +#include <linux/platform_device.h> + +/** + * struct dbx500_regulator_info - dbx500 regulator information + * @dev: device pointer + * @desc: regulator description + * @rdev: regulator device pointer + * @is_enabled: status of the regulator + * @epod_id: id for EPOD (power domain) + * @is_ramret: RAM retention switch for EPOD (power domain) + * @operating_point: operating point (only for vape, to be removed) + * + */ +struct dbx500_regulator_info { + struct device *dev; + struct regulator_desc desc; + struct regulator_dev *rdev; + bool is_enabled; + u16 epod_id; + bool is_ramret; + bool exclude_from_power_state; + unsigned int operating_point; +}; + void power_state_active_enable(void); int power_state_active_disable(void); + +#ifdef CONFIG_REGULATOR_DEBUG +int ux500_regulator_debug_init(struct platform_device *pdev, + struct dbx500_regulator_info *regulator_info, + int num_regulators); + +int ux500_regulator_debug_exit(void); +#else + +static inline int ux500_regulator_debug_init(struct platform_device *pdev, + struct dbx500_regulator_info *regulator_info, + int num_regulators) {} + +static inline int ux500_regulator_debug_exit(void) {} +#endif #endif |