hwmon: (pmbus/core) Generalise pmbus get status
authorNaresh Solanki <naresh.solanki@9elements.com>
Wed, 1 Mar 2023 16:44:32 +0000 (17:44 +0100)
committerGuenter Roeck <linux@roeck-us.net>
Wed, 19 Apr 2023 14:08:32 +0000 (07:08 -0700)
Add function pmbus get status that can be used to get both pmbus
specific status & regulator status

Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
...
Change in V4
- None
Changes in V3:
- Add pmbus_is_enabled function
Changes in V2:
- Add __maybe attribute for pmbus_get_status function
- Remove unrelated changes
Link: https://lore.kernel.org/r/20230301164434.1928237-2-Naresh.Solanki@9elements.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/pmbus/pmbus_core.c

index 1b70cf3..f8ac901 100644 (file)
@@ -2735,18 +2735,12 @@ static const struct pmbus_status_category __maybe_unused pmbus_status_flag_map[]
        },
 };
 
-#if IS_ENABLED(CONFIG_REGULATOR)
-static int pmbus_regulator_is_enabled(struct regulator_dev *rdev)
+static int _pmbus_is_enabled(struct device *dev, u8 page)
 {
-       struct device *dev = rdev_get_dev(rdev);
        struct i2c_client *client = to_i2c_client(dev->parent);
-       struct pmbus_data *data = i2c_get_clientdata(client);
-       u8 page = rdev_get_id(rdev);
        int ret;
 
-       mutex_lock(&data->update_lock);
        ret = _pmbus_read_byte_data(client, page, PMBUS_OPERATION);
-       mutex_unlock(&data->update_lock);
 
        if (ret < 0)
                return ret;
@@ -2754,58 +2748,38 @@ static int pmbus_regulator_is_enabled(struct regulator_dev *rdev)
        return !!(ret & PB_OPERATION_CONTROL_ON);
 }
 
-static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable)
+static int __maybe_unused pmbus_is_enabled(struct device *dev, u8 page)
 {
-       struct device *dev = rdev_get_dev(rdev);
        struct i2c_client *client = to_i2c_client(dev->parent);
        struct pmbus_data *data = i2c_get_clientdata(client);
-       u8 page = rdev_get_id(rdev);
        int ret;
 
        mutex_lock(&data->update_lock);
-       ret = pmbus_update_byte_data(client, page, PMBUS_OPERATION,
-                                    PB_OPERATION_CONTROL_ON,
-                                    enable ? PB_OPERATION_CONTROL_ON : 0);
+       ret = _pmbus_is_enabled(dev, page);
        mutex_unlock(&data->update_lock);
 
-       return ret;
-}
-
-static int pmbus_regulator_enable(struct regulator_dev *rdev)
-{
-       return _pmbus_regulator_on_off(rdev, 1);
-}
-
-static int pmbus_regulator_disable(struct regulator_dev *rdev)
-{
-       return _pmbus_regulator_on_off(rdev, 0);
+       return !!(ret & PB_OPERATION_CONTROL_ON);
 }
 
-static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
+static int _pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flags)
 {
        int i, status;
        const struct pmbus_status_category *cat;
        const struct pmbus_status_assoc *bit;
-       struct device *dev = rdev_get_dev(rdev);
-       struct i2c_client *client = to_i2c_client(dev->parent);
-       struct pmbus_data *data = i2c_get_clientdata(client);
-       u8 page = rdev_get_id(rdev);
+       struct device *dev = data->dev;
+       struct i2c_client *client = to_i2c_client(dev);
        int func = data->info->func[page];
 
        *flags = 0;
 
-       mutex_lock(&data->update_lock);
-
        for (i = 0; i < ARRAY_SIZE(pmbus_status_flag_map); i++) {
                cat = &pmbus_status_flag_map[i];
                if (!(func & cat->func))
                        continue;
 
                status = _pmbus_read_byte_data(client, page, cat->reg);
-               if (status < 0) {
-                       mutex_unlock(&data->update_lock);
+               if (status < 0)
                        return status;
-               }
 
                for (bit = cat->bits; bit->pflag; bit++) {
                        if (status & bit->pflag)
@@ -2823,11 +2797,10 @@ static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned
         * REGULATOR_ERROR_<foo>_WARN.
         */
        status = pmbus_get_status(client, page, PMBUS_STATUS_WORD);
-       mutex_unlock(&data->update_lock);
        if (status < 0)
                return status;
 
-       if (pmbus_regulator_is_enabled(rdev)) {
+       if (_pmbus_is_enabled(dev, page)) {
                if (status & PB_STATUS_OFF)
                        *flags |= REGULATOR_ERROR_FAIL;
 
@@ -2855,6 +2828,59 @@ static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned
        return 0;
 }
 
+static int __maybe_unused pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flags)
+{
+       int ret;
+
+       mutex_lock(&data->update_lock);
+       ret = _pmbus_get_flags(data, page, flags);
+       mutex_unlock(&data->update_lock);
+
+       return ret;
+}
+
+#if IS_ENABLED(CONFIG_REGULATOR)
+static int pmbus_regulator_is_enabled(struct regulator_dev *rdev)
+{
+       return pmbus_is_enabled(rdev_get_dev(rdev), rdev_get_id(rdev));
+}
+
+static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable)
+{
+       struct device *dev = rdev_get_dev(rdev);
+       struct i2c_client *client = to_i2c_client(dev->parent);
+       struct pmbus_data *data = i2c_get_clientdata(client);
+       u8 page = rdev_get_id(rdev);
+       int ret;
+
+       mutex_lock(&data->update_lock);
+       ret = pmbus_update_byte_data(client, page, PMBUS_OPERATION,
+                                    PB_OPERATION_CONTROL_ON,
+                                    enable ? PB_OPERATION_CONTROL_ON : 0);
+       mutex_unlock(&data->update_lock);
+
+       return ret;
+}
+
+static int pmbus_regulator_enable(struct regulator_dev *rdev)
+{
+       return _pmbus_regulator_on_off(rdev, 1);
+}
+
+static int pmbus_regulator_disable(struct regulator_dev *rdev)
+{
+       return _pmbus_regulator_on_off(rdev, 0);
+}
+
+static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
+{
+       struct device *dev = rdev_get_dev(rdev);
+       struct i2c_client *client = to_i2c_client(dev->parent);
+       struct pmbus_data *data = i2c_get_clientdata(client);
+
+       return pmbus_get_flags(data, rdev_get_id(rdev), flags);
+}
+
 static int pmbus_regulator_get_status(struct regulator_dev *rdev)
 {
        struct device *dev = rdev_get_dev(rdev);