summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>2011-09-07 12:28:30 +0200
committerRabin Vincent <rabin.vincent@stericsson.com>2011-09-22 15:41:17 +0530
commitcbac4637451932ebb5f8174690dd14e00e41fc40 (patch)
tree7cfa582225529504e56f8b1ba60da459aa8394b4
parentbbdf20e0def58afa0863de47adae86877d237e93 (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.h8
-rw-r--r--arch/arm/mach-ux500/pm/suspend.c3
-rw-r--r--arch/arm/mach-ux500/regulator-ux500.c151
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;