mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-26 14:17:26 -04:00
hwmon: (pwm-fan) Use devm_thermal_of_cooling_device_register
Use devm_thermal_of_cooling_device_register() to register the cooling device. Also use devm_add_action_or_reset() to stop the fan on device removal, and to disable the pwm. Introduce a local 'dev' variable in the probe function to make the code easier to read. As a side effect, this fixes a bug seen if pwm_fan_of_get_cooling_data() returned an error. In that situation, the pwm was not disabled, and the fan was not stopped. Using devm functions also ensures that the pwm is disabled and that the fan is stopped only after the hwmon device has been unregistered. Cc: Lukasz Majewski <l.majewski@samsung.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
This commit is contained in:
parent
0b2a785db8
commit
37bcec5d9f
1 changed files with 29 additions and 44 deletions
|
@ -207,33 +207,44 @@ static int pwm_fan_of_get_cooling_data(struct device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pwm_fan_regulator_disable(void *data)
|
||||||
|
{
|
||||||
|
regulator_disable(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pwm_fan_pwm_disable(void *data)
|
||||||
|
{
|
||||||
|
pwm_disable(data);
|
||||||
|
}
|
||||||
|
|
||||||
static int pwm_fan_probe(struct platform_device *pdev)
|
static int pwm_fan_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct thermal_cooling_device *cdev;
|
struct thermal_cooling_device *cdev;
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
struct pwm_fan_ctx *ctx;
|
struct pwm_fan_ctx *ctx;
|
||||||
struct device *hwmon;
|
struct device *hwmon;
|
||||||
int ret;
|
int ret;
|
||||||
struct pwm_state state = { };
|
struct pwm_state state = { };
|
||||||
|
|
||||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
mutex_init(&ctx->lock);
|
mutex_init(&ctx->lock);
|
||||||
|
|
||||||
ctx->pwm = devm_of_pwm_get(&pdev->dev, pdev->dev.of_node, NULL);
|
ctx->pwm = devm_of_pwm_get(dev, dev->of_node, NULL);
|
||||||
if (IS_ERR(ctx->pwm)) {
|
if (IS_ERR(ctx->pwm)) {
|
||||||
ret = PTR_ERR(ctx->pwm);
|
ret = PTR_ERR(ctx->pwm);
|
||||||
|
|
||||||
if (ret != -EPROBE_DEFER)
|
if (ret != -EPROBE_DEFER)
|
||||||
dev_err(&pdev->dev, "Could not get PWM: %d\n", ret);
|
dev_err(dev, "Could not get PWM: %d\n", ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, ctx);
|
platform_set_drvdata(pdev, ctx);
|
||||||
|
|
||||||
ctx->reg_en = devm_regulator_get_optional(&pdev->dev, "fan");
|
ctx->reg_en = devm_regulator_get_optional(dev, "fan");
|
||||||
if (IS_ERR(ctx->reg_en)) {
|
if (IS_ERR(ctx->reg_en)) {
|
||||||
if (PTR_ERR(ctx->reg_en) != -ENODEV)
|
if (PTR_ERR(ctx->reg_en) != -ENODEV)
|
||||||
return PTR_ERR(ctx->reg_en);
|
return PTR_ERR(ctx->reg_en);
|
||||||
|
@ -242,10 +253,11 @@ static int pwm_fan_probe(struct platform_device *pdev)
|
||||||
} else {
|
} else {
|
||||||
ret = regulator_enable(ctx->reg_en);
|
ret = regulator_enable(ctx->reg_en);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(dev, "Failed to enable fan supply: %d\n", ret);
|
||||||
"Failed to enable fan supply: %d\n", ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
devm_add_action_or_reset(dev, pwm_fan_regulator_disable,
|
||||||
|
ctx->reg_en);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->pwm_value = MAX_PWM;
|
ctx->pwm_value = MAX_PWM;
|
||||||
|
@ -257,62 +269,36 @@ static int pwm_fan_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
ret = pwm_apply_state(ctx->pwm, &state);
|
ret = pwm_apply_state(ctx->pwm, &state);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "Failed to configure PWM\n");
|
dev_err(dev, "Failed to configure PWM\n");
|
||||||
goto err_reg_disable;
|
return ret;
|
||||||
}
|
}
|
||||||
|
devm_add_action_or_reset(dev, pwm_fan_pwm_disable, ctx->pwm);
|
||||||
|
|
||||||
hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "pwmfan",
|
hwmon = devm_hwmon_device_register_with_groups(dev, "pwmfan",
|
||||||
ctx, pwm_fan_groups);
|
ctx, pwm_fan_groups);
|
||||||
if (IS_ERR(hwmon)) {
|
if (IS_ERR(hwmon)) {
|
||||||
dev_err(&pdev->dev, "Failed to register hwmon device\n");
|
dev_err(dev, "Failed to register hwmon device\n");
|
||||||
ret = PTR_ERR(hwmon);
|
return PTR_ERR(hwmon);
|
||||||
goto err_pwm_disable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pwm_fan_of_get_cooling_data(&pdev->dev, ctx);
|
ret = pwm_fan_of_get_cooling_data(dev, ctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ctx->pwm_fan_state = ctx->pwm_fan_max_state;
|
ctx->pwm_fan_state = ctx->pwm_fan_max_state;
|
||||||
if (IS_ENABLED(CONFIG_THERMAL)) {
|
if (IS_ENABLED(CONFIG_THERMAL)) {
|
||||||
cdev = thermal_of_cooling_device_register(pdev->dev.of_node,
|
cdev = devm_thermal_of_cooling_device_register(dev,
|
||||||
"pwm-fan", ctx,
|
dev->of_node, "pwm-fan", ctx, &pwm_fan_cooling_ops);
|
||||||
&pwm_fan_cooling_ops);
|
|
||||||
if (IS_ERR(cdev)) {
|
if (IS_ERR(cdev)) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(dev,
|
||||||
"Failed to register pwm-fan as cooling device");
|
"Failed to register pwm-fan as cooling device");
|
||||||
ret = PTR_ERR(cdev);
|
return PTR_ERR(cdev);
|
||||||
goto err_pwm_disable;
|
|
||||||
}
|
}
|
||||||
ctx->cdev = cdev;
|
ctx->cdev = cdev;
|
||||||
thermal_cdev_update(cdev);
|
thermal_cdev_update(cdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_pwm_disable:
|
|
||||||
state.enabled = false;
|
|
||||||
pwm_apply_state(ctx->pwm, &state);
|
|
||||||
|
|
||||||
err_reg_disable:
|
|
||||||
if (ctx->reg_en)
|
|
||||||
regulator_disable(ctx->reg_en);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pwm_fan_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
thermal_cooling_device_unregister(ctx->cdev);
|
|
||||||
if (ctx->pwm_value)
|
|
||||||
pwm_disable(ctx->pwm);
|
|
||||||
|
|
||||||
if (ctx->reg_en)
|
|
||||||
regulator_disable(ctx->reg_en);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
@ -380,7 +366,6 @@ MODULE_DEVICE_TABLE(of, of_pwm_fan_match);
|
||||||
|
|
||||||
static struct platform_driver pwm_fan_driver = {
|
static struct platform_driver pwm_fan_driver = {
|
||||||
.probe = pwm_fan_probe,
|
.probe = pwm_fan_probe,
|
||||||
.remove = pwm_fan_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "pwm-fan",
|
.name = "pwm-fan",
|
||||||
.pm = &pwm_fan_pm,
|
.pm = &pwm_fan_pm,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue