summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/db5500-prcmu.c55
-rw-r--r--drivers/regulator/dbx500-prcmu.c91
-rw-r--r--include/linux/regulator/db5500-prcmu.h2
-rw-r--r--include/linux/regulator/dbx500-prcmu.h92
4 files changed, 202 insertions, 38 deletions
diff --git a/drivers/regulator/db5500-prcmu.c b/drivers/regulator/db5500-prcmu.c
index 4da49c1d4ce..bf2aeeee399 100644
--- a/drivers/regulator/db5500-prcmu.c
+++ b/drivers/regulator/db5500-prcmu.c
@@ -16,34 +16,13 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/db5500-prcmu.h>
-#include <linux/mfd/dbx500-prcmu.h>
-#include "dbx500-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 <linux/mfd/dbx500-prcmu.h>
+#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/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c
index f2e5ecdc586..5f3157c09a9 100644
--- a/drivers/regulator/dbx500-prcmu.c
+++ b/drivers/regulator/dbx500-prcmu.c
@@ -119,6 +119,97 @@ static const struct file_operations ux500_regulator_power_state_cnt_fops = {
.owner = THIS_MODULE,
};
+struct ux500_regulator {
+ char *name;
+ void (*enable)(void);
+ int (*disable)(void);
+};
+static struct ux500_regulator ux500_atomic_regulators[] = {
+ {
+ .name = "dma40.0",
+ .enable = power_state_active_enable,
+ .disable = power_state_active_disable,
+ },
+ {
+ .name = "ssp0",
+ .enable = power_state_active_enable,
+ .disable = power_state_active_disable,
+ },
+ {
+ .name = "ssp1",
+ .enable = power_state_active_enable,
+ .disable = power_state_active_disable,
+ },
+ {
+ .name = "spi0",
+ .enable = power_state_active_enable,
+ .disable = power_state_active_disable,
+ },
+ {
+ .name = "spi1",
+ .enable = power_state_active_enable,
+ .disable = power_state_active_disable,
+ },
+ {
+ .name = "spi2",
+ .enable = power_state_active_enable,
+ .disable = power_state_active_disable,
+ },
+ {
+ .name = "spi3",
+ .enable = power_state_active_enable,
+ .disable = power_state_active_disable,
+ },
+ {
+ .name = "cryp1",
+ .enable = power_state_active_enable,
+ .disable = power_state_active_disable,
+ },
+ {
+ .name = "hash1",
+ .enable = power_state_active_enable,
+ .disable = power_state_active_disable,
+ },
+};
+
+struct ux500_regulator *__must_check ux500_regulator_get(struct device *dev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ux500_atomic_regulators); i++) {
+ if (!strcmp(dev_name(dev), ux500_atomic_regulators[i].name))
+ return &ux500_atomic_regulators[i];
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(ux500_regulator_get);
+
+int ux500_regulator_atomic_enable(struct ux500_regulator *regulator)
+{
+ if (regulator) {
+ regulator->enable();
+ return 0;
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(ux500_regulator_atomic_enable);
+
+int ux500_regulator_atomic_disable(struct ux500_regulator *regulator)
+{
+ if (regulator)
+ return regulator->disable();
+ else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(ux500_regulator_atomic_disable);
+
+void ux500_regulator_put(struct ux500_regulator *regulator)
+{
+ /* Here for symetric reasons and for possible future use */
+}
+EXPORT_SYMBOL_GPL(ux500_regulator_put);
+
static int ux500_regulator_status_print(struct seq_file *s, void *p)
{
struct device *dev = s->private;
diff --git a/include/linux/regulator/db5500-prcmu.h b/include/linux/regulator/db5500-prcmu.h
index c5701e4fd2c..fee68795867 100644
--- a/include/linux/regulator/db5500-prcmu.h
+++ b/include/linux/regulator/db5500-prcmu.h
@@ -11,6 +11,8 @@
#ifndef __DB5500_REGULATOR_H__
#define __DB5500_REGULATOR_H__
+#include <linux/regulator/dbx500-prcmu.h>
+
/* Number of DB5500 regulators and regulator enumeration */
enum db5500_regulator_id {
DB5500_REGULATOR_VAPE,
diff --git a/include/linux/regulator/dbx500-prcmu.h b/include/linux/regulator/dbx500-prcmu.h
new file mode 100644
index 00000000000..2ecb34c56aa
--- /dev/null
+++ b/include/linux/regulator/dbx500-prcmu.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) ST Ericsson SA 2011
+ *
+ * License Terms: GNU General Public License v2
+ *
+ */
+#ifndef __LINUX_REGULATOR_DBX500_H
+#define __LINUX_REGULATOR_DBX500_H
+
+struct ux500_regulator;
+
+#ifdef CONFIG_REGULATOR
+/*
+ * NOTE! The device will be connected to the correct regulator by this
+ * new framework. A list with connections will match up dev_name(dev)
+ * to the specific regulator. This follows the same principle as the
+ * normal regulator framework.
+ *
+ * This framework shall only be used in special cases when a regulator
+ * has to be enabled/disabled in atomic context.
+ */
+
+/**
+ * ux500_regulator_get()
+ *
+ * @dev: Drivers device struct
+ *
+ * Returns a ux500_regulator struct. Shall be used as argument for
+ * ux500_regulator_atomic_enable/disable calls.
+ * Return ERR_PTR(-EINVAL) upon no matching regulator found.
+ */
+struct ux500_regulator *__must_check ux500_regulator_get(struct device *dev);
+
+/**
+ * ux500_regulator_atomic_enable()
+ *
+ * @regulator: Regulator handle, provided from ux500_regulator_get.
+ *
+ * The enable/disable functions keep an internal counter, so every
+ * enable must be paired with an disable in order to turn off regulator.
+ */
+int ux500_regulator_atomic_enable(struct ux500_regulator *regulator);
+
+/**
+ * ux500_regulator_atomic_disable()
+ *
+ * @regulator: Regulator handle, provided from ux500_regulator_get.
+ *
+ */
+int ux500_regulator_atomic_disable(struct ux500_regulator *regulator);
+
+/**
+ * ux500_regulator_put()
+ *
+ * @regulator: Regulator handle, provided from ux500_regulator_get.
+ */
+void ux500_regulator_put(struct ux500_regulator *regulator);
+
+#else
+
+static inline struct ux500_regulator *__must_check
+ux500_regulator_get(struct device *dev)
+{
+ return ERR_PTR(-EINVAL);
+}
+
+static inline int
+ux500_regulator_atomic_enable(struct ux500_regulator *regulator)
+{
+ return -EINVAL;
+}
+
+static inline int
+ux500_regulator_atomic_disable(struct ux500_regulator *regulator)
+{
+ return -EINVAL;
+}
+
+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