summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>2011-09-07 12:28:30 +0200
committerRobert Marklund <robert.marklund@stericsson.com>2011-10-05 13:01:17 +0200
commit1d4e311d63be8308451b89d7e7174a2c4722de2f (patch)
tree36b7fd550948d4679c2d312270f69d4cfe7d10b8
parente86aea9c20c792507694711e0927eac9200218ea (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>
-rw-r--r--arch/arm/mach-ux500/pm/suspend.c4
-rw-r--r--drivers/regulator/db5500-prcmu.c53
-rw-r--r--drivers/regulator/db8500-prcmu.c59
-rw-r--r--drivers/regulator/dbx500-prcmu.c134
-rw-r--r--drivers/regulator/dbx500-prcmu.h39
-rw-r--r--include/linux/regulator/dbx500-prcmu.h8
6 files changed, 222 insertions, 75 deletions
diff --git a/arch/arm/mach-ux500/pm/suspend.c b/arch/arm/mach-ux500/pm/suspend.c
index 06ddd9ea20d..d64faa99a3a 100644
--- a/arch/arm/mach-ux500/pm/suspend.c
+++ b/arch/arm/mach-ux500/pm/suspend.c
@@ -13,6 +13,8 @@
#include <linux/mfd/dbx500-prcmu.h>
#include <linux/gpio/nomadik.h>
#include <linux/regulator/ab8500-debug.h>
+#include <linux/regulator/dbx500-prcmu.h>
+#include <linux/mfd/dbx500-prcmu.h>
#include <mach/context.h>
#include <mach/pm.h>
@@ -197,11 +199,13 @@ 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/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
diff --git a/include/linux/regulator/dbx500-prcmu.h b/include/linux/regulator/dbx500-prcmu.h
index 789c535c748..2ecb34c56aa 100644
--- a/include/linux/regulator/dbx500-prcmu.h
+++ b/include/linux/regulator/dbx500-prcmu.h
@@ -81,4 +81,12 @@ static inline void ux500_regulator_put(struct ux500_regulator *regulator)
}
#endif /* CONFIG_REGULATOR */
+#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