From 8d9bcc63e41f8709a1bf08f07010b55aa33db48d Mon Sep 17 00:00:00 2001 From: Dongjin Kim Date: Wed, 30 Jun 2021 11:38:33 +0900 Subject: [PATCH 03/16] ODROID-COMMON: hwmon: (pwm-fan): fix to add 'pwm1_enable' to set PWM fan mode Change-Id: If0562f497703b8660206dad80d7933902bbf53e4 --- drivers/hwmon/pwm-fan.c | 67 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index f12b9a28a232..383a24316985 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -44,6 +45,7 @@ struct pwm_fan_ctx { unsigned int pwm_fan_max_state; unsigned int *pwm_fan_cooling_levels; struct thermal_cooling_device *cdev; + int enable; struct hwmon_chip_info info; struct hwmon_channel_info fan_channel; @@ -99,6 +101,10 @@ static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) struct pwm_state *state = &ctx->pwm_state; mutex_lock(&ctx->lock); + + if (!ctx->enable) + pwm = MAX_PWM; + if (ctx->pwm_value == pwm) goto exit_set_pwm_err; @@ -183,6 +189,51 @@ static const struct hwmon_ops pwm_fan_hwmon_ops = { .write = pwm_fan_write, }; +static ssize_t enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); + int err; + unsigned long val; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; + + mutex_lock(&ctx->lock); + ctx->enable = val; + mutex_unlock(&ctx->lock); + + err = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[ctx->pwm_fan_state]); + + return err ? err : count; +} + +static ssize_t enable_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); + + return sprintf(buf, "%u\n", ctx->enable); +} + +static SENSOR_DEVICE_ATTR_RW(pwm1_enable, enable, 0); + +static struct attribute *pwm_fan_attrs[] = { + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + NULL, +}; + +static const struct attribute_group pwm_fan_group = { + .attrs = pwm_fan_attrs, +}; + +static const struct attribute_group *pwm_fan_groups[] = { + &pwm_fan_group, + NULL, +}; + /* thermal cooling device callbacks */ static int pwm_fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) @@ -214,7 +265,7 @@ static int pwm_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) { struct pwm_fan_ctx *ctx = cdev->devdata; - int ret; + int ret = 0; if (!ctx || (state > ctx->pwm_fan_max_state)) return -EINVAL; @@ -222,10 +273,12 @@ pwm_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) if (state == ctx->pwm_fan_state) return 0; - ret = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]); - if (ret) { - dev_err(&cdev->device, "Cannot set pwm!\n"); - return ret; + if (ctx->enable >= 2) { + ret = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]); + if (ret) { + dev_err(&cdev->device, "Cannot set pwm!\n"); + return ret; + } } ctx->pwm_fan_state = state; @@ -316,6 +369,8 @@ static int pwm_fan_probe(struct platform_device *pdev) if (IS_ERR(ctx->pwm)) return dev_err_probe(dev, PTR_ERR(ctx->pwm), "Could not get PWM\n"); + ctx->enable = 2; + platform_set_drvdata(pdev, ctx); ctx->reg_en = devm_regulator_get_optional(dev, "fan"); @@ -434,7 +489,7 @@ static int pwm_fan_probe(struct platform_device *pdev) ctx->info.info = channels; hwmon = devm_hwmon_device_register_with_info(dev, "pwmfan", - ctx, &ctx->info, NULL); + ctx, &ctx->info, pwm_fan_groups); if (IS_ERR(hwmon)) { dev_err(dev, "Failed to register hwmon device\n"); return PTR_ERR(hwmon); -- 2.34.1