diff options
author | Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> | 2011-09-07 12:28:30 +0200 |
---|---|---|
committer | Rabin Vincent <rabin.vincent@stericsson.com> | 2011-09-22 15:41:17 +0530 |
commit | cbac4637451932ebb5f8174690dd14e00e41fc40 (patch) | |
tree | 7cfa582225529504e56f8b1ba60da459aa8394b4 | |
parent | bbdf20e0def58afa0863de47adae86877d237e93 (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: Id4c33c776e54abc23df9243996d1cfa749e1e679
Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/30359
Tested-by: Karl KOMIEROWSKI <karl.komierowski@stericsson.com>
Reviewed-by: QABUILD
Reviewed-by: Karl KOMIEROWSKI <karl.komierowski@stericsson.com>
-rw-r--r-- | arch/arm/mach-ux500/include/mach/regulator.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-ux500/pm/suspend.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-ux500/regulator-ux500.c | 151 |
3 files changed, 160 insertions, 2 deletions
diff --git a/arch/arm/mach-ux500/include/mach/regulator.h b/arch/arm/mach-ux500/include/mach/regulator.h index 75ff3340359..18c0a011a8f 100644 --- a/arch/arm/mach-ux500/include/mach/regulator.h +++ b/arch/arm/mach-ux500/include/mach/regulator.h @@ -85,4 +85,12 @@ static inline void ux500_regulator_put(struct ux500_regulator *regulator) } #endif +#ifdef CONFIG_REGULATOR_DEBUG +void ux500_regulator_suspend_debug(void); +void ux500_regulator_resume_debug(void); +#else +static inline void ux500_regulator_suspend_debug(void) { } +static inline void ux500_regulator_resume_debug(void) { } +#endif + #endif diff --git a/arch/arm/mach-ux500/pm/suspend.c b/arch/arm/mach-ux500/pm/suspend.c index ef3eaa64bf1..f0a9433b9fb 100644 --- a/arch/arm/mach-ux500/pm/suspend.c +++ b/arch/arm/mach-ux500/pm/suspend.c @@ -19,6 +19,7 @@ #include <mach/prcmu.h> #include <mach/prcmu-regs.h> #include <mach/prcmu-qos.h> +#include <mach/regulator.h> #include "context.h" #include "pm.h" @@ -201,12 +202,14 @@ static int ux500_suspend_prepare_late(void) /* ESRAM to retention instead of OFF until ROM is fixed */ (void)prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); ab8500_regulator_debug_force(); + ux500_regulator_suspend_debug(); return 0; } static void ux500_suspend_wake(void) { + ux500_regulator_resume_debug(); ab8500_regulator_debug_restore(); (void)prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); } diff --git a/arch/arm/mach-ux500/regulator-ux500.c b/arch/arm/mach-ux500/regulator-ux500.c index 638ff231d60..f0abe605941 100644 --- a/arch/arm/mach-ux500/regulator-ux500.c +++ b/arch/arm/mach-ux500/regulator-ux500.c @@ -18,11 +18,154 @@ #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/slab.h> #include "regulator-ux500.h" #include <mach/prcmu.h> +#ifdef CONFIG_REGULATOR_DEBUG + +static struct ux500_regulator_debug { + struct dentry *dir; + struct dentry *status_file; + struct u8500_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 u8500_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, +}; + +static int __devinit +ux500_regulator_debug_init(struct platform_device *pdev, + struct u8500_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; +} + +static int __devexit ux500_regulator_debug_exit(void) +{ + debugfs_remove_recursive(rdebug.dir); + kfree(rdebug.state_after_suspend); + kfree(rdebug.state_before_suspend); + + return 0; +} + +#else + +static inline int +ux500_regulator_debug_init(struct platform_device *pdev, + struct u8500_regulator_info *regulator_info, + int num_regulators) {} + +static inline int ux500_regulator_debug_exit(void) {} + +#endif + /* * power state reference count */ @@ -391,7 +534,9 @@ ux500_regulator_probe(struct platform_device *pdev, "regulator-%s-probed\n", info->desc.name); } - return 0; + err = ux500_regulator_debug_init(pdev, regulator_info, num_regulators); + + return err; } int __devexit @@ -399,7 +544,9 @@ ux500_regulator_remove(struct platform_device *pdev, struct u8500_regulator_info *regulator_info, int num_regulators) { - int i; + int i; + + ux500_regulator_debug_exit(); for (i = 0; i < num_regulators; i++) { struct u8500_regulator_info *info; |