regulator: core: Add new API to poll for error conditions
authorAxel Haslam <ahaslam@baylibre.com>
Thu, 3 Nov 2016 11:11:42 +0000 (12:11 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 4 Nov 2016 18:15:25 +0000 (12:15 -0600)
Regulator consumers can receive event notifications when
errors are reported to the driver, but currently, there is
no way for a regulator consumer to know when the error is over.

To allow a regulator consumer to poll for error conditions
add a new API: regulator_get_error_flags.

Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/regulator/core.c
include/linux/regulator/consumer.h
include/linux/regulator/driver.h

index 67426c0..08260c2 100644 (file)
@@ -3359,6 +3359,39 @@ unsigned int regulator_get_mode(struct regulator *regulator)
 }
 EXPORT_SYMBOL_GPL(regulator_get_mode);
 
+static int _regulator_get_error_flags(struct regulator_dev *rdev,
+                                       unsigned int *flags)
+{
+       int ret;
+
+       mutex_lock(&rdev->mutex);
+
+       /* sanity check */
+       if (!rdev->desc->ops->get_error_flags) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = rdev->desc->ops->get_error_flags(rdev, flags);
+out:
+       mutex_unlock(&rdev->mutex);
+       return ret;
+}
+
+/**
+ * regulator_get_error_flags - get regulator error information
+ * @regulator: regulator source
+ * @flags: pointer to store error flags
+ *
+ * Get the current regulator error information.
+ */
+int regulator_get_error_flags(struct regulator *regulator,
+                               unsigned int *flags)
+{
+       return _regulator_get_error_flags(regulator->rdev, flags);
+}
+EXPORT_SYMBOL_GPL(regulator_get_error_flags);
+
 /**
  * regulator_set_load - set regulator load
  * @regulator: regulator source
index 6921082..528eb1f 100644 (file)
@@ -120,6 +120,25 @@ struct regmap;
 #define REGULATOR_EVENT_PRE_DISABLE            0x400
 #define REGULATOR_EVENT_ABORT_DISABLE          0x800
 
+/*
+ * Regulator errors that can be queried using regulator_get_error_flags
+ *
+ * UNDER_VOLTAGE  Regulator output is under voltage.
+ * OVER_CURRENT   Regulator output current is too high.
+ * REGULATION_OUT Regulator output is out of regulation.
+ * FAIL           Regulator output has failed.
+ * OVER_TEMP      Regulator over temp.
+ *
+ * NOTE: These errors can be OR'ed together.
+ */
+
+#define REGULATOR_ERROR_UNDER_VOLTAGE          BIT(1)
+#define REGULATOR_ERROR_OVER_CURRENT           BIT(2)
+#define REGULATOR_ERROR_REGULATION_OUT         BIT(3)
+#define REGULATOR_ERROR_FAIL                   BIT(4)
+#define REGULATOR_ERROR_OVER_TEMP              BIT(5)
+
+
 /**
  * struct pre_voltage_change_data - Data sent with PRE_VOLTAGE_CHANGE event
  *
@@ -237,6 +256,8 @@ int regulator_get_current_limit(struct regulator *regulator);
 
 int regulator_set_mode(struct regulator *regulator, unsigned int mode);
 unsigned int regulator_get_mode(struct regulator *regulator);
+int regulator_get_error_flags(struct regulator *regulator,
+                               unsigned int *flags);
 int regulator_set_load(struct regulator *regulator, int load_uA);
 
 int regulator_allow_bypass(struct regulator *regulator, bool allow);
@@ -477,6 +498,11 @@ static inline unsigned int regulator_get_mode(struct regulator *regulator)
        return REGULATOR_MODE_NORMAL;
 }
 
+static inline int regulator_get_error_flags(struct regulator *regulator)
+{
+       return -EINVAL;
+}
+
 static inline int regulator_set_load(struct regulator *regulator, int load_uA)
 {
        return REGULATOR_MODE_NORMAL;
index 37b5324..dac8e7b 100644 (file)
@@ -100,6 +100,7 @@ struct regulator_linear_range {
  *
  * @set_mode: Set the configured operating mode for the regulator.
  * @get_mode: Get the configured operating mode for the regulator.
+ * @get_error_flags: Get the current error(s) for the regulator.
  * @get_status: Return actual (not as-configured) status of regulator, as a
  *     REGULATOR_STATUS value (or negative errno)
  * @get_optimum_mode: Get the most efficient operating mode for the regulator
@@ -169,6 +170,9 @@ struct regulator_ops {
        int (*set_mode) (struct regulator_dev *, unsigned int mode);
        unsigned int (*get_mode) (struct regulator_dev *);
 
+       /* retrieve current error flags on the regulator */
+       int (*get_error_flags)(struct regulator_dev *, unsigned int *flags);
+
        /* Time taken to enable or set voltage on the regulator */
        int (*enable_time) (struct regulator_dev *);
        int (*set_ramp_delay) (struct regulator_dev *, int ramp_delay);