From patchwork Mon May 23 11:05:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Stein X-Patchwork-Id: 1634511 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=FBHKZCKX; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=Dfb10s2u; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4L6DyL2n41z9sGl for ; Mon, 23 May 2022 21:05:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234437AbiEWLF2 (ORCPT ); Mon, 23 May 2022 07:05:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34998 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234264AbiEWLF1 (ORCPT ); Mon, 23 May 2022 07:05:27 -0400 Received: from mx1.tq-group.com (mx1.tq-group.com [93.104.207.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12F53101D0; Mon, 23 May 2022 04:05:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303926; x=1684839926; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=N4fNOLo/O2++wVgHbraL4AIatNPwANhDsXLsREGO28k=; b=FBHKZCKXI0GhQ5bWoahwcBRGOMbNGwtC/SKbmCvZm0qA4Y00l0nLc9DN oJi3oDhxHhVuGZ3APXe2yFSqQbhsNIg8lJPhf+i2G4/l0po0sX2keBxWt HM7Qmt3n5+1F4Jhh7gx6/SOf0oEhGuQgLFPWlZdCeAXQkNpgnIqdnJR4j j2oKSvUFg7fDwQeUGLh2Szjpaun7CamCMERA5U3gUWUvZbNzkYKW8wjik 5QK5gFGnUYwWluS8X1YIHKJ44D5I44ef505PQJZfWDf2uzzbsXf6mNr8r 55N5U0w4krr2TBV8xTUKB0mkNUZvH/FDEcU9ZwzFkZFslFz6cZ1/B+Y5e w==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031366" Received: from unknown (HELO tq-pgp-pr1.tq-net.de) ([192.168.6.15]) by mx1-pgp.tq-group.com with ESMTP; 23 May 2022 13:05:18 +0200 Received: from mx1.tq-group.com ([192.168.6.7]) by tq-pgp-pr1.tq-net.de (PGP Universal service); Mon, 23 May 2022 13:05:18 +0200 X-PGP-Universal: processed; by tq-pgp-pr1.tq-net.de on Mon, 23 May 2022 13:05:18 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303918; x=1684839918; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=N4fNOLo/O2++wVgHbraL4AIatNPwANhDsXLsREGO28k=; b=Dfb10s2uvl8lOhQsuxFCPb18Yx3MZuayLzNQJJ3ZIGB/gZbFdBCPae2m Vvlm795eDMN3f7/53LAZRGcDiTSw4nHTYSqXwWCntgCJMePryrMAvqZsY 1d+CFLVHPyot1cxLga48CDTKvSQPxSA+ikZF7dBGQYZwhimi3aDuK9nDU 441ZKaoguu5m4hYl9zfx89t/orcycVAjJ7e+ZsiFcR2Llo0Z6YXsS3CQw e6cphxmB0grqVA7ONRnYc4sL1FpNI0+o47R5tpRnZ5EOP5XD0dnr34BFs rHc7qtN1gw03Gp0iZcHbYO50U0l51m4UAl9A+UGyj9CI17HMQUouBXk4q w==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031365" Received: from vtuxmail01.tq-net.de ([10.115.0.20]) by mx1.tq-group.com with ESMTP; 23 May 2022 13:05:18 +0200 Received: from steina-w.tq-net.de (unknown [10.123.49.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by vtuxmail01.tq-net.de (Postfix) with ESMTPSA id 33939280075; Mon, 23 May 2022 13:05:18 +0200 (CEST) From: Alexander Stein To: Jean Delvare , Guenter Roeck , Jonathan Corbet , Thierry Reding , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Lee Jones Cc: Alexander Stein , linux-hwmon@vger.kernel.org, linux-pwm@vger.kernel.org, Markus Niebel Subject: [PATCH v4 1/6] hwmon: pwm-fan: Refactor fan power on/off Date: Mon, 23 May 2022 13:05:08 +0200 Message-Id: <20220523110513.407516-2-alexander.stein@ew.tq-group.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> References: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, URIBL_CSS_A autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org In preparation for dynamically switching regulator, split the power on and power off sequence into separate functions. Signed-off-by: Alexander Stein Reviewed-by: Guenter Roeck --- drivers/hwmon/pwm-fan.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index 6c08551d8d14..831878daffe6 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -82,23 +82,47 @@ static void sample_timer(struct timer_list *t) mod_timer(&ctx->rpm_timer, jiffies + HZ); } -static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) +static int pwm_fan_power_on(struct pwm_fan_ctx *ctx) { + struct pwm_state *state = &ctx->pwm_state; unsigned long period; - int ret = 0; + int ret; + + period = state->period; + state->duty_cycle = DIV_ROUND_UP(ctx->pwm_value * (period - 1), MAX_PWM); + state->enabled = true; + ret = pwm_apply_state(ctx->pwm, state); + + return ret; +} + +static int pwm_fan_power_off(struct pwm_fan_ctx *ctx) +{ struct pwm_state *state = &ctx->pwm_state; + state->enabled = false; + state->duty_cycle = 0; + pwm_apply_state(ctx->pwm, state); + + return 0; +} + +static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) +{ + int ret = 0; + mutex_lock(&ctx->lock); if (ctx->pwm_value == pwm) goto exit_set_pwm_err; - period = state->period; - state->duty_cycle = DIV_ROUND_UP(pwm * (period - 1), MAX_PWM); - state->enabled = pwm ? true : false; + if (pwm > 0) + ret = pwm_fan_power_on(ctx); + else + ret = pwm_fan_power_off(ctx); - ret = pwm_apply_state(ctx->pwm, state); if (!ret) ctx->pwm_value = pwm; + exit_set_pwm_err: mutex_unlock(&ctx->lock); return ret; From patchwork Mon May 23 11:05:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Stein X-Patchwork-Id: 1634512 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=aLHq3dsw; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=Bd+nrmOR; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4L6DyM72PVz9sGl for ; Mon, 23 May 2022 21:05:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234438AbiEWLFa (ORCPT ); Mon, 23 May 2022 07:05:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35022 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234264AbiEWLF3 (ORCPT ); Mon, 23 May 2022 07:05:29 -0400 Received: from mx1.tq-group.com (mx1.tq-group.com [93.104.207.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4995217E33; Mon, 23 May 2022 04:05:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303927; x=1684839927; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/cAEHkHWSmpF0ROyxA/wCo1gDxMoa4uQunb5Hpc/roU=; b=aLHq3dswWyM2jqucryPHXOPJUXYg0KogzKcYWrGgIvm+TxaZrCQnBB8L GuSxo+0BbagNE7mm6UoJu3Rl1qsODb5Xsq3VqZY3DPyrPp8/oEYpwvcnr AZAVH6zJ+DhjfOAxL7F2z80BV2R7MyAZ6BKegGCa64wEiasmiVxwMLQtH vEJo0tJnYVNw5fToJaicnMTRRbhXepIcGeQP1cscrxGSjSTsYVtTH1nwp IlXHT7/bVQMNsaaeoQg9M3AFZ24MvAugl2qf/2vJ969jYVPY4YRvcUOpQ sn5S2Oh+qItnwhHOassH3xQ1DSiGeH7FfBHuxLC0w0aEQHOo7axMEhFsI w==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031368" Received: from unknown (HELO tq-pgp-pr1.tq-net.de) ([192.168.6.15]) by mx1-pgp.tq-group.com with ESMTP; 23 May 2022 13:05:18 +0200 Received: from mx1.tq-group.com ([192.168.6.7]) by tq-pgp-pr1.tq-net.de (PGP Universal service); Mon, 23 May 2022 13:05:18 +0200 X-PGP-Universal: processed; by tq-pgp-pr1.tq-net.de on Mon, 23 May 2022 13:05:18 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303918; x=1684839918; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/cAEHkHWSmpF0ROyxA/wCo1gDxMoa4uQunb5Hpc/roU=; b=Bd+nrmORCCQsc6qMJS7ZDy5bTSAyV+Ih3ABkKPjTGz293Y9+TzLHkTMf Rbpk+gFXH7OlCeyDrJrqUW0HkA/+yR4a6MmT4pO5/qFH/nP1yFXngNJ8B qKLfLyK0eb4jhMVmJVSjL8WbQNnZzAURrI0QRbZj4DodHof1+aVmFCQzw YebDQWbz1McGUX1IRLmvurdtaHG+PkZ6xgKoUvRimwrUdROu2rRN4zErl s/77D28LV/ZePeRBCVn/PPMGbPZiZeXvZh3bWGJZgA/iELH84y8BR6qeZ k5X0/au+5txYswUfqO3NO7lpMTItGdmvxltjZwZRjIc2YAeScRrJL1YNa Q==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031367" Received: from vtuxmail01.tq-net.de ([10.115.0.20]) by mx1.tq-group.com with ESMTP; 23 May 2022 13:05:18 +0200 Received: from steina-w.tq-net.de (unknown [10.123.49.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by vtuxmail01.tq-net.de (Postfix) with ESMTPSA id 65080280078; Mon, 23 May 2022 13:05:18 +0200 (CEST) From: Alexander Stein To: Jean Delvare , Guenter Roeck , Jonathan Corbet , Thierry Reding , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Lee Jones Cc: Alexander Stein , linux-hwmon@vger.kernel.org, linux-pwm@vger.kernel.org, Markus Niebel Subject: [PATCH v4 2/6] hwmon: pwm-fan: Simplify enable/disable check Date: Mon, 23 May 2022 13:05:09 +0200 Message-Id: <20220523110513.407516-3-alexander.stein@ew.tq-group.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> References: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, URIBL_CSS_A autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org Instead of comparing the current to the new pwm duty to decide whether to enable the PWM, use a dedicated flag. Also apply the new PWM duty in any case. This is a preparation to enable/disable the regulator dynamically. Signed-off-by: Alexander Stein --- drivers/hwmon/pwm-fan.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index 831878daffe6..96b10d422828 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -29,10 +29,13 @@ struct pwm_fan_tach { }; struct pwm_fan_ctx { + struct device *dev; + struct mutex lock; struct pwm_device *pwm; struct pwm_state pwm_state; struct regulator *reg_en; + bool enabled; int tach_count; struct pwm_fan_tach *tachs; @@ -85,14 +88,21 @@ static void sample_timer(struct timer_list *t) static int pwm_fan_power_on(struct pwm_fan_ctx *ctx) { struct pwm_state *state = &ctx->pwm_state; - unsigned long period; int ret; - period = state->period; - state->duty_cycle = DIV_ROUND_UP(ctx->pwm_value * (period - 1), MAX_PWM); + if (ctx->enabled) + return 0; + state->enabled = true; ret = pwm_apply_state(ctx->pwm, state); + if (ret) { + dev_err(ctx->dev, "failed to enable PWM\n"); + goto err; + } + ctx->enabled = true; + +err: return ret; } @@ -100,26 +110,36 @@ static int pwm_fan_power_off(struct pwm_fan_ctx *ctx) { struct pwm_state *state = &ctx->pwm_state; + if (!ctx->enabled) + return 0; + state->enabled = false; state->duty_cycle = 0; pwm_apply_state(ctx->pwm, state); + ctx->enabled = false; + return 0; } static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) { + struct pwm_state *state = &ctx->pwm_state; + unsigned long period; int ret = 0; mutex_lock(&ctx->lock); - if (ctx->pwm_value == pwm) - goto exit_set_pwm_err; - if (pwm > 0) + if (pwm > 0) { + period = state->period; + state->duty_cycle = DIV_ROUND_UP(pwm * (period - 1), MAX_PWM); + ret = pwm_apply_state(ctx->pwm, state); + if (ret) + goto exit_set_pwm_err; ret = pwm_fan_power_on(ctx); - else + } else { ret = pwm_fan_power_off(ctx); - + } if (!ret) ctx->pwm_value = pwm; @@ -326,6 +346,7 @@ static int pwm_fan_probe(struct platform_device *pdev) mutex_init(&ctx->lock); + ctx->dev = &pdev->dev; ctx->pwm = devm_of_pwm_get(dev, dev->of_node, NULL); if (IS_ERR(ctx->pwm)) return dev_err_probe(dev, PTR_ERR(ctx->pwm), "Could not get PWM\n"); From patchwork Mon May 23 11:05:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Stein X-Patchwork-Id: 1634513 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=dSt1H88Z; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=eHL8kAIk; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4L6DyQ3Fzwz9sGG for ; Mon, 23 May 2022 21:05:34 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234454AbiEWLFc (ORCPT ); Mon, 23 May 2022 07:05:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35046 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234441AbiEWLFa (ORCPT ); Mon, 23 May 2022 07:05:30 -0400 Received: from mx1.tq-group.com (mx1.tq-group.com [93.104.207.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F4DE18346; Mon, 23 May 2022 04:05:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303928; x=1684839928; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RZSNcjfq2xPUXOnuE4OSU5ARSJIozOw0E0Ak4xm71EM=; b=dSt1H88Zap0Z9nhwfadAcU7ExOMmVxkuuHA6LjDW2F0XZLSxJSz789nd RusHil9QkSj+TrpuXX4gOTvBOIPKJirn54p45uRNn68m622naBK1VV1Vb 6TJHIX4LDuPEUM+T4ABjU4EdtY4UR/5Jkzf8nO4DBgQdHde1l1zVRC6MT aLtfrrrJsCxFClQdaqjAwDhmm6D2cXhp20LpIs9K7/v6k0jsaZ7J3H5l7 Ruu1O/mWbEeX+fCm5LD1ojtkWxMHFhLiaBpTKRHumSizszu/6E21aqrTC 6xJov5Rr6X+8is38a+2sxdjEi34wySibxWTlIC7q8vxFmqiFbyeulLkvF Q==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031372" Received: from unknown (HELO tq-pgp-pr1.tq-net.de) ([192.168.6.15]) by mx1-pgp.tq-group.com with ESMTP; 23 May 2022 13:05:19 +0200 Received: from mx1.tq-group.com ([192.168.6.7]) by tq-pgp-pr1.tq-net.de (PGP Universal service); Mon, 23 May 2022 13:05:19 +0200 X-PGP-Universal: processed; by tq-pgp-pr1.tq-net.de on Mon, 23 May 2022 13:05:19 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303919; x=1684839919; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RZSNcjfq2xPUXOnuE4OSU5ARSJIozOw0E0Ak4xm71EM=; b=eHL8kAIkeUFJtSGbCT3nN4KFGYO9d3g/J1yv/hOA83n+MqCzG1g174bO zZr76mRupkeRixx5Zo84kbHSeF+96Bf+azCJIkYZFJmLsjGgz9kq1yMp2 fCkWna2zniynDOi8VrXRo65oiNSKnY7wvjwB5jbnAaECZIQskjemgl6rS xMtPOqu7RU08PlvtEdDWiGh+qo1ifLrwW8cNI5sJQlEi8svmSV+624TkP MrG8F57l132k1Uo6RYwjtoPwvtVLOS9W3Hgw8lVYx2NnHoieLUFe9hSPf 7wpzVDZCMHG5kdORd+Y6Cqn9I3/cxJPO9U2RXdw2+x5RaXme3H43FFCLv g==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031371" Received: from vtuxmail01.tq-net.de ([10.115.0.20]) by mx1.tq-group.com with ESMTP; 23 May 2022 13:05:19 +0200 Received: from steina-w.tq-net.de (unknown [10.123.49.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by vtuxmail01.tq-net.de (Postfix) with ESMTPSA id 9BEB3280070; Mon, 23 May 2022 13:05:18 +0200 (CEST) From: Alexander Stein To: Jean Delvare , Guenter Roeck , Jonathan Corbet , Thierry Reding , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Lee Jones Cc: Alexander Stein , linux-hwmon@vger.kernel.org, linux-pwm@vger.kernel.org, Markus Niebel Subject: [PATCH v4 3/6] hwmon: pwm-fan: Add dedicated power switch function Date: Mon, 23 May 2022 13:05:10 +0200 Message-Id: <20220523110513.407516-4-alexander.stein@ew.tq-group.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> References: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, URIBL_CSS_A autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org This handles enabling/disabling the regulator in a single function, while keeping the enables/disabled balanced. This is a preparation when regulator is switched from different code paths. Signed-off-by: Alexander Stein --- drivers/hwmon/pwm-fan.c | 52 +++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index 96b10d422828..04af24268963 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -35,6 +35,7 @@ struct pwm_fan_ctx { struct pwm_device *pwm; struct pwm_state pwm_state; struct regulator *reg_en; + bool regulator_enabled; bool enabled; int tach_count; @@ -85,6 +86,29 @@ static void sample_timer(struct timer_list *t) mod_timer(&ctx->rpm_timer, jiffies + HZ); } +static int pwm_fan_switch_power(struct pwm_fan_ctx *ctx, bool on) +{ + int ret = 0; + + if (!ctx->reg_en) + return ret; + + if (ctx->regulator_enabled && on) { + ret = 0; + } else if (!ctx->regulator_enabled && on) { + ret = regulator_enable(ctx->reg_en); + if (ret == 0) + ctx->regulator_enabled = true; + } else if (ctx->regulator_enabled && !on) { + ret = regulator_disable(ctx->reg_en); + if (ret == 0) + ctx->regulator_enabled = false; + } else if (!ctx->regulator_enabled && !on) { + ret = 0; + } + return ret; +} + static int pwm_fan_power_on(struct pwm_fan_ctx *ctx) { struct pwm_state *state = &ctx->pwm_state; @@ -316,7 +340,9 @@ static int pwm_fan_of_get_cooling_data(struct device *dev, static void pwm_fan_regulator_disable(void *data) { - regulator_disable(data); + struct pwm_fan_ctx *ctx = data; + + pwm_fan_switch_power(ctx, false); } static void pwm_fan_pwm_disable(void *__ctx) @@ -360,13 +386,13 @@ static int pwm_fan_probe(struct platform_device *pdev) ctx->reg_en = NULL; } else { - ret = regulator_enable(ctx->reg_en); + ret = pwm_fan_switch_power(ctx, true); if (ret) { dev_err(dev, "Failed to enable fan supply: %d\n", ret); return ret; } ret = devm_add_action_or_reset(dev, pwm_fan_regulator_disable, - ctx->reg_en); + ctx); if (ret) return ret; } @@ -512,12 +538,10 @@ static int pwm_fan_disable(struct device *dev) return ret; } - if (ctx->reg_en) { - ret = regulator_disable(ctx->reg_en); - if (ret) { - dev_err(dev, "Failed to disable fan supply: %d\n", ret); - return ret; - } + ret = pwm_fan_switch_power(ctx, false); + if (ret) { + dev_err(dev, "Failed to disable fan supply: %d\n", ret); + return ret; } return 0; @@ -539,12 +563,10 @@ static int pwm_fan_resume(struct device *dev) struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); int ret; - if (ctx->reg_en) { - ret = regulator_enable(ctx->reg_en); - if (ret) { - dev_err(dev, "Failed to enable fan supply: %d\n", ret); - return ret; - } + ret = pwm_fan_switch_power(ctx, true); + if (ret) { + dev_err(dev, "Failed to enable fan supply: %d\n", ret); + return ret; } if (ctx->pwm_value == 0) From patchwork Mon May 23 11:05:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Stein X-Patchwork-Id: 1634514 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=QWBAn0eR; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=Kjd+CYlF; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4L6DyQ5c04z9sGl for ; Mon, 23 May 2022 21:05:34 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234441AbiEWLFe (ORCPT ); Mon, 23 May 2022 07:05:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35062 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234450AbiEWLFa (ORCPT ); Mon, 23 May 2022 07:05:30 -0400 Received: from mx1.tq-group.com (mx1.tq-group.com [93.104.207.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 604793122D; Mon, 23 May 2022 04:05:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303929; x=1684839929; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GPXm7BZeX5DgNj1DNqvkm7tf4Ol3dCj610giwTyo8+I=; b=QWBAn0eRzUNmCegd4/rfSt/4AfcOTekxqhMbfimLoiySzTZFi0Nvvwvn IhaOp3gBS43PNmW0MvkdI7Me27dHhma+d+FtezOr2VzqUCe5X0grBNnI7 d6tpv3mmWkJJZ+svhbqK1V/zle/LgpF7t93MDciS0T/4Ei9LNusWBgcqO wIq3mdhNXjQxHzsxcwvz11MeFSnYKYjELYjmwFBehto+DYwzAlXXtvZAz fMxR7P5nndpNui9ENdKpYCLbam/MOgSre/nUIDXR8yPxU0r9Oke8zl1UF tka+HlgpLH45F6DQc2pd9D+FXbT97tTFu89w0dlrbB1Z22WMNuXQDGK/L g==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031374" Received: from unknown (HELO tq-pgp-pr1.tq-net.de) ([192.168.6.15]) by mx1-pgp.tq-group.com with ESMTP; 23 May 2022 13:05:19 +0200 Received: from mx1.tq-group.com ([192.168.6.7]) by tq-pgp-pr1.tq-net.de (PGP Universal service); Mon, 23 May 2022 13:05:19 +0200 X-PGP-Universal: processed; by tq-pgp-pr1.tq-net.de on Mon, 23 May 2022 13:05:19 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303919; x=1684839919; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GPXm7BZeX5DgNj1DNqvkm7tf4Ol3dCj610giwTyo8+I=; b=Kjd+CYlFtFLEq7NnzfyO7SNhQigyvyuRFWQ57vnxS20Jm8EtNTWF2xvT AqDI7izw/XvZHinnbloHaSqc8dkOixtjBZ02t314bODlDMMfXXVeOLKPU 7AOyNQoDua+rKm+hvaQg6wi2OSmQIHBir28N7R8tEZ8ABIS96fZ8ygClz fKsT+8dTz80rWrDQBycqphOdXMLceAT3KgeDddVhF2p83TaJn1zIweRvR 7JWdWwkYNhQnZmwQ5E90vmRWBtehXfpVrDiM4oED0wXrnT6ZzVRQWj1wo t5d6JwXNniNxSaCABySIEe1kSLsvACmLJ6v5GQkWJAXPcHBwt6kL5fnPa w==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031373" Received: from vtuxmail01.tq-net.de ([10.115.0.20]) by mx1.tq-group.com with ESMTP; 23 May 2022 13:05:19 +0200 Received: from steina-w.tq-net.de (unknown [10.123.49.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by vtuxmail01.tq-net.de (Postfix) with ESMTPSA id CD4DB280075; Mon, 23 May 2022 13:05:18 +0200 (CEST) From: Alexander Stein To: Jean Delvare , Guenter Roeck , Jonathan Corbet , Thierry Reding , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Lee Jones Cc: Alexander Stein , linux-hwmon@vger.kernel.org, linux-pwm@vger.kernel.org, Markus Niebel Subject: [PATCH v4 4/6] hwmon: pwm-fan: split __set_pwm into locked/unlocked functions Date: Mon, 23 May 2022 13:05:11 +0200 Message-Id: <20220523110513.407516-5-alexander.stein@ew.tq-group.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> References: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, URIBL_CSS_A autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org Regular calls to set_pwm don't hold the mutex, but the upcoming update_enable support needs to call set_pwm with the mutex being held. So provide the previous behavior in set_pwm (handling the lock), while adding __set_pwm which assumes the lock being held. Signed-off-by: Alexander Stein Reviewed-by: Guenter Roeck --- drivers/hwmon/pwm-fan.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index 04af24268963..fcc1b7b55a65 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -152,14 +152,12 @@ static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) unsigned long period; int ret = 0; - mutex_lock(&ctx->lock); - if (pwm > 0) { period = state->period; state->duty_cycle = DIV_ROUND_UP(pwm * (period - 1), MAX_PWM); ret = pwm_apply_state(ctx->pwm, state); if (ret) - goto exit_set_pwm_err; + return ret; ret = pwm_fan_power_on(ctx); } else { ret = pwm_fan_power_off(ctx); @@ -167,8 +165,17 @@ static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) if (!ret) ctx->pwm_value = pwm; -exit_set_pwm_err: + return ret; +} + +static int set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) +{ + int ret; + + mutex_lock(&ctx->lock); + ret = __set_pwm(ctx, pwm); mutex_unlock(&ctx->lock); + return ret; } @@ -192,7 +199,7 @@ static int pwm_fan_write(struct device *dev, enum hwmon_sensor_types type, if (val < 0 || val > MAX_PWM) return -EINVAL; - ret = __set_pwm(ctx, val); + ret = set_pwm(ctx, val); if (ret) return ret; @@ -280,7 +287,7 @@ 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]); + ret = set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]); if (ret) { dev_err(&cdev->device, "Cannot set pwm!\n"); return ret; @@ -400,7 +407,7 @@ static int pwm_fan_probe(struct platform_device *pdev) pwm_init_state(ctx->pwm, &ctx->pwm_state); /* - * __set_pwm assumes that MAX_PWM * (period - 1) fits into an unsigned + * set_pwm assumes that MAX_PWM * (period - 1) fits into an unsigned * long. Check this here to prevent the fan running at a too low * frequency. */ @@ -410,7 +417,7 @@ static int pwm_fan_probe(struct platform_device *pdev) } /* Set duty cycle to maximum allowed and enable PWM output */ - ret = __set_pwm(ctx, MAX_PWM); + ret = set_pwm(ctx, MAX_PWM); if (ret) { dev_err(dev, "Failed to configure PWM: %d\n", ret); return ret; From patchwork Mon May 23 11:05:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Stein X-Patchwork-Id: 1634515 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=lJiYDdPV; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=P7sDnV8I; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4L6DyR2CW7z9sGG for ; Mon, 23 May 2022 21:05:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234450AbiEWLFe (ORCPT ); Mon, 23 May 2022 07:05:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234264AbiEWLFb (ORCPT ); Mon, 23 May 2022 07:05:31 -0400 Received: from mx1.tq-group.com (mx1.tq-group.com [93.104.207.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C26D17E33; Mon, 23 May 2022 04:05:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303929; x=1684839929; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ecSMPA6CEeNkEL0oD+cFhQMJsVmMfYhT1VOqZf+Zi4E=; b=lJiYDdPVUAxNYw9ujngzctfo6RzSaLbq1496/Kw9yntWey2q0Ewjmh5a 29FKGsfxmJEm8N8DpDIq7f4LvPyfNYU4OcXEvILViHZhL9IyuG5x3X9lF vl5EOC4UrUkvqNxHFg87ModYILBtfW8dDcyMnnVur1PVMGbOtblnXaHbH zHIHmXB5V/bCM3ONVZDlu4I56GQ/rJtpO0dbxtt1bpBy3nAdcjZ2xuirh RICxOHze7kvsPZ57nuDeAjre5tnhBnJwIETpyjCduQJdkFPhKDm+PEnKq n5Ke2dWAy9tG38TY1I2X3GCOf8+AZNueahx6YyH/8pMU5Jj4zpZv+UDf/ A==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031376" Received: from unknown (HELO tq-pgp-pr1.tq-net.de) ([192.168.6.15]) by mx1-pgp.tq-group.com with ESMTP; 23 May 2022 13:05:19 +0200 Received: from mx1.tq-group.com ([192.168.6.7]) by tq-pgp-pr1.tq-net.de (PGP Universal service); Mon, 23 May 2022 13:05:19 +0200 X-PGP-Universal: processed; by tq-pgp-pr1.tq-net.de on Mon, 23 May 2022 13:05:19 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303919; x=1684839919; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ecSMPA6CEeNkEL0oD+cFhQMJsVmMfYhT1VOqZf+Zi4E=; b=P7sDnV8IxY8+RCQZrWLt6mrTj39OBojiejncGHAxccf34y/0EtQHIlWT nNjKTGEUTHiJjFD92tR41AWbg7crwKu2xteFvrpjbUoJnjTV8L9bpYNnx qi6h9Q7UOiz48zDEan9G6LT5MK1Zol/e1MvQDXwvRiZODAqwtRwz1oXkX atCc2eORHmuphbrK/r6jeICLJacVYin0yBXv0otYQTNb9+9MiucWWLIVj 7PfeoX12WaeeURxLmYrZwbt+8D5INB3N4fNmQr/3j75f1FmfdFaLkb7HH GG3UrVjaumBGz5CvKXNOKgxAgKi05Ds1h0Rx57LsSiOIIejJczy/7ioUe Q==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031375" Received: from vtuxmail01.tq-net.de ([10.115.0.20]) by mx1.tq-group.com with ESMTP; 23 May 2022 13:05:19 +0200 Received: from steina-w.tq-net.de (unknown [10.123.49.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by vtuxmail01.tq-net.de (Postfix) with ESMTPSA id 09F3E280078; Mon, 23 May 2022 13:05:19 +0200 (CEST) From: Alexander Stein To: Jean Delvare , Guenter Roeck , Jonathan Corbet , Thierry Reding , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Lee Jones Cc: Alexander Stein , linux-hwmon@vger.kernel.org, linux-pwm@vger.kernel.org, Markus Niebel Subject: [PATCH v4 5/6] hwmon: pwm-fan: Switch regulator dynamically Date: Mon, 23 May 2022 13:05:12 +0200 Message-Id: <20220523110513.407516-6-alexander.stein@ew.tq-group.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> References: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, URIBL_CSS_A autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org This adds the enable attribute which is used to select if zero PWM duty means to switch off regulator and PWM or to keep them enabled but at inactive PWM output level. Depending on the select enable mode, turn off the regulator and PWM if the PWM duty is zero, or keep them enabled. This is especially important for fan using inverted PWM signal polarity. Having regulator supplied and PWM disabled, some PWM controllers provide the active, rather than inactive signal. With this change the shutdown as well as suspend/resume paths require modifcations as well. Signed-off-by: Alexander Stein --- Documentation/hwmon/pwm-fan.rst | 12 ++ drivers/hwmon/pwm-fan.c | 213 +++++++++++++++++++++----------- 2 files changed, 154 insertions(+), 71 deletions(-) diff --git a/Documentation/hwmon/pwm-fan.rst b/Documentation/hwmon/pwm-fan.rst index 82fe96742fee..f77998b204ef 100644 --- a/Documentation/hwmon/pwm-fan.rst +++ b/Documentation/hwmon/pwm-fan.rst @@ -18,3 +18,15 @@ the hwmon's sysfs interface. The fan rotation speed returned via the optional 'fan1_input' is extrapolated from the sampled interrupts from the tachometer signal within 1 second. + +The driver provides the following sensor accesses in sysfs: + +=============== ======= ======================================================= +fan1_input ro fan tachometer speed in RPM +pwm1_enable rw keep enable mode, defines behaviour when pwm1=0 + 0 -> disable pwm and regulator + 1 -> enable pwm; if pwm==0, disable pwm, keep regulator enabled + 2 -> enable pwm; if pwm==0, keep pwm and regulator enabled + 3 -> enable pwm; if pwm==0, disable pwm and regulator +pwm1 rw relative speed (0-255), 255=max. speed. +=============== ======= ======================================================= diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index fcc1b7b55a65..e5d4b3b1cc49 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -28,6 +28,13 @@ struct pwm_fan_tach { u8 pulses_per_revolution; }; +enum pwm_fan_enable_mode { + pwm_off_reg_off, + pwm_disable_reg_enable, + pwm_enable_reg_enable, + pwm_disable_reg_disable, +}; + struct pwm_fan_ctx { struct device *dev; @@ -35,6 +42,7 @@ struct pwm_fan_ctx { struct pwm_device *pwm; struct pwm_state pwm_state; struct regulator *reg_en; + enum pwm_fan_enable_mode enable_mode; bool regulator_enabled; bool enabled; @@ -86,6 +94,29 @@ static void sample_timer(struct timer_list *t) mod_timer(&ctx->rpm_timer, jiffies + HZ); } +static void pwm_fan_enable_mode_2_state(int enable_mode, + struct pwm_state *state, + bool *enable_regulator) +{ + switch (enable_mode) { + case pwm_disable_reg_enable: + /* disable pwm, keep regulator enabled */ + state->enabled = false; + *enable_regulator = true; + break; + case pwm_enable_reg_enable: + /* keep pwm and regulator enabled */ + state->enabled = true; + *enable_regulator = true; + break; + case pwm_off_reg_off: + case pwm_disable_reg_disable: + /* disable pwm and regulator */ + state->enabled = false; + *enable_regulator = false; + } +} + static int pwm_fan_switch_power(struct pwm_fan_ctx *ctx, bool on) { int ret = 0; @@ -117,30 +148,46 @@ static int pwm_fan_power_on(struct pwm_fan_ctx *ctx) if (ctx->enabled) return 0; + ret = pwm_fan_switch_power(ctx, true); + if (ret < 0) { + dev_err(ctx->dev, "failed to enable power supply\n"); + return ret; + } + state->enabled = true; ret = pwm_apply_state(ctx->pwm, state); if (ret) { dev_err(ctx->dev, "failed to enable PWM\n"); - goto err; + goto disable_regulator; } ctx->enabled = true; -err: + return 0; + +disable_regulator: + pwm_fan_switch_power(ctx, false); return ret; } static int pwm_fan_power_off(struct pwm_fan_ctx *ctx) { struct pwm_state *state = &ctx->pwm_state; + bool enable_regulator = false; if (!ctx->enabled) return 0; + pwm_fan_enable_mode_2_state(ctx->enable_mode, + state, + &enable_regulator); + state->enabled = false; state->duty_cycle = 0; pwm_apply_state(ctx->pwm, state); + pwm_fan_switch_power(ctx, enable_regulator); + ctx->enabled = false; return 0; @@ -153,6 +200,10 @@ static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) int ret = 0; if (pwm > 0) { + if (ctx->enable_mode == pwm_off_reg_off) + /* pwm-fan hard disabled */ + return 0; + period = state->period; state->duty_cycle = DIV_ROUND_UP(pwm * (period - 1), MAX_PWM); ret = pwm_apply_state(ctx->pwm, state); @@ -190,20 +241,76 @@ static void pwm_fan_update_state(struct pwm_fan_ctx *ctx, unsigned long pwm) ctx->pwm_fan_state = i; } +static int pwm_fan_update_enable(struct pwm_fan_ctx *ctx, long val) +{ + int ret = 0; + int old_val; + + mutex_lock(&ctx->lock); + + if (ctx->enable_mode == val) + goto out; + + old_val = ctx->enable_mode; + ctx->enable_mode = val; + + if (val == 0) { + /* Disable pwm-fan unconditionally */ + ret = __set_pwm(ctx, 0); + if (ret) + ctx->enable_mode = old_val; + pwm_fan_update_state(ctx, 0); + } else { + /* + * Change PWM and/or regulator state if currently disabled + * Nothing to do if currently enabled + */ + if (!ctx->enabled) { + struct pwm_state *state = &ctx->pwm_state; + bool enable_regulator = false; + + state->duty_cycle = 0; + pwm_fan_enable_mode_2_state(val, + state, + &enable_regulator); + + pwm_apply_state(ctx->pwm, state); + pwm_fan_switch_power(ctx, enable_regulator); + pwm_fan_update_state(ctx, 0); + } + } +out: + mutex_unlock(&ctx->lock); + + return ret; +} + static int pwm_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long val) { struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); int ret; - if (val < 0 || val > MAX_PWM) - return -EINVAL; + switch (attr) { + case hwmon_pwm_input: + if (val < 0 || val > MAX_PWM) + return -EINVAL; + ret = set_pwm(ctx, val); + if (ret) + return ret; + pwm_fan_update_state(ctx, val); + break; + case hwmon_pwm_enable: + if (val < 0 || val > 3) + ret = -EINVAL; + else + ret = pwm_fan_update_enable(ctx, val); - ret = set_pwm(ctx, val); - if (ret) return ret; + default: + return -EOPNOTSUPP; + } - pwm_fan_update_state(ctx, val); return 0; } @@ -214,9 +321,15 @@ static int pwm_fan_read(struct device *dev, enum hwmon_sensor_types type, switch (type) { case hwmon_pwm: - *val = ctx->pwm_value; - return 0; - + switch (attr) { + case hwmon_pwm_input: + *val = ctx->pwm_value; + return 0; + case hwmon_pwm_enable: + *val = ctx->enable_mode; + return 0; + } + return -EOPNOTSUPP; case hwmon_fan: *val = ctx->tachs[channel].rpm; return 0; @@ -345,20 +458,14 @@ static int pwm_fan_of_get_cooling_data(struct device *dev, return 0; } -static void pwm_fan_regulator_disable(void *data) -{ - struct pwm_fan_ctx *ctx = data; - - pwm_fan_switch_power(ctx, false); -} - -static void pwm_fan_pwm_disable(void *__ctx) +static void pwm_fan_cleanup(void *__ctx) { struct pwm_fan_ctx *ctx = __ctx; - ctx->pwm_state.enabled = false; - pwm_apply_state(ctx->pwm, &ctx->pwm_state); del_timer_sync(&ctx->rpm_timer); + /* Switch off everything */ + ctx->enable_mode = pwm_disable_reg_disable; + pwm_fan_power_off(ctx); } static int pwm_fan_probe(struct platform_device *pdev) @@ -392,16 +499,6 @@ static int pwm_fan_probe(struct platform_device *pdev) return PTR_ERR(ctx->reg_en); ctx->reg_en = NULL; - } else { - ret = pwm_fan_switch_power(ctx, true); - if (ret) { - dev_err(dev, "Failed to enable fan supply: %d\n", ret); - return ret; - } - ret = devm_add_action_or_reset(dev, pwm_fan_regulator_disable, - ctx); - if (ret) - return ret; } pwm_init_state(ctx->pwm, &ctx->pwm_state); @@ -416,14 +513,19 @@ static int pwm_fan_probe(struct platform_device *pdev) return -EINVAL; } - /* Set duty cycle to maximum allowed and enable PWM output */ + ctx->enable_mode = pwm_disable_reg_enable; + + /* + * Set duty cycle to maximum allowed and enable PWM output as well as + * the regulator. In case of error nothing is changed + */ ret = set_pwm(ctx, MAX_PWM); if (ret) { dev_err(dev, "Failed to configure PWM: %d\n", ret); return ret; } timer_setup(&ctx->rpm_timer, sample_timer, 0); - ret = devm_add_action_or_reset(dev, pwm_fan_pwm_disable, ctx); + ret = devm_add_action_or_reset(dev, pwm_fan_cleanup, ctx); if (ret) return ret; @@ -455,7 +557,7 @@ static int pwm_fan_probe(struct platform_device *pdev) if (!channels) return -ENOMEM; - channels[0] = HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT); + channels[0] = HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_ENABLE); for (i = 0; i < ctx->tach_count; i++) { struct pwm_fan_tach *tach = &ctx->tachs[i]; @@ -529,57 +631,26 @@ static int pwm_fan_probe(struct platform_device *pdev) return 0; } -static int pwm_fan_disable(struct device *dev) -{ - struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); - int ret; - - if (ctx->pwm_value) { - /* keep ctx->pwm_state unmodified for pwm_fan_resume() */ - struct pwm_state state = ctx->pwm_state; - - state.duty_cycle = 0; - state.enabled = false; - ret = pwm_apply_state(ctx->pwm, &state); - if (ret < 0) - return ret; - } - - ret = pwm_fan_switch_power(ctx, false); - if (ret) { - dev_err(dev, "Failed to disable fan supply: %d\n", ret); - return ret; - } - - return 0; -} - static void pwm_fan_shutdown(struct platform_device *pdev) { - pwm_fan_disable(&pdev->dev); + struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev); + + pwm_fan_cleanup(ctx); } #ifdef CONFIG_PM_SLEEP static int pwm_fan_suspend(struct device *dev) { - return pwm_fan_disable(dev); + struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); + + return pwm_fan_power_off(ctx); } static int pwm_fan_resume(struct device *dev) { struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); - int ret; - - ret = pwm_fan_switch_power(ctx, true); - if (ret) { - dev_err(dev, "Failed to enable fan supply: %d\n", ret); - return ret; - } - - if (ctx->pwm_value == 0) - return 0; - return pwm_apply_state(ctx->pwm, &ctx->pwm_state); + return set_pwm(ctx, ctx->pwm_value); } #endif From patchwork Mon May 23 11:05:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Stein X-Patchwork-Id: 1634516 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=UDPh34Up; dkim=pass (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.a=rsa-sha256 header.s=key1 header.b=moatUu0y; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4L6DyS1GQrz9sGl for ; Mon, 23 May 2022 21:05:36 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234459AbiEWLFf (ORCPT ); Mon, 23 May 2022 07:05:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234451AbiEWLFc (ORCPT ); Mon, 23 May 2022 07:05:32 -0400 Received: from mx1.tq-group.com (mx1.tq-group.com [93.104.207.81]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 718E418E0D; Mon, 23 May 2022 04:05:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303930; x=1684839930; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zkD9EPLd7PBjo+JjCvtRWIRLMDAYVEJ2yfUNmCB2e+k=; b=UDPh34UpF25bgBFcqPKwOE7nS/mGE7s4/gnCOq4DdZ8KeUW22hWb65B3 AqNhHuynArzhl3toSkHh1kAXqa8QtZh7ZogVbmrIHmuU4WFeymOwOUKQ1 h1hL8c600i2d5UhcKeJYBulk2LrdcJQOhgubaOFBeItCSm4VB+8XqgShl 43TlEx9/plY+IfIki+pqtdlr3eqRRQh9Ff9Wv12yTti9UWCCZ175Tldj3 rwNjkET81+aaveEsYGXIGa+pyDWduQjM9+jVYDI4VBP+cO8uB4mJz760s qu3Sj7WCJaFQdbaMUqmTgDDK7G/igFiTYeQx2TEutpR+Y4if2ka24VQK7 g==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031378" Received: from unknown (HELO tq-pgp-pr1.tq-net.de) ([192.168.6.15]) by mx1-pgp.tq-group.com with ESMTP; 23 May 2022 13:05:19 +0200 Received: from mx1.tq-group.com ([192.168.6.7]) by tq-pgp-pr1.tq-net.de (PGP Universal service); Mon, 23 May 2022 13:05:19 +0200 X-PGP-Universal: processed; by tq-pgp-pr1.tq-net.de on Mon, 23 May 2022 13:05:19 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1653303919; x=1684839919; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zkD9EPLd7PBjo+JjCvtRWIRLMDAYVEJ2yfUNmCB2e+k=; b=moatUu0y0++bXvH6gvlzD0IYzDUVN1q/qB8+ilzHyX5L7zfoU4lGoiO8 xG9up6Ouju0TA3yL3MooxtemVr53ICuVwtV8itCEibXZ6WHtxx4bqVgul bTpCAMPlYGBWNc/X3h4Dh+97TuzbVQfJHuGjUb8IYSvjRhkg1txbdWHQA 5fn0LkZ7AkgkmdL2U4CNShlumWFvosf853dx2AtaVelQBI+qpNqSWpJfq x0js9kAvG0CBRAh+DvNqLeMEClbhLKJ4yMVPCvg+WnoW0hL90bEQmkhAc xh/x7fzbYjY+YJcNRF8EK037pb77euCzoCT1KazofYqVzGEczM5pR+U69 A==; X-IronPort-AV: E=Sophos;i="5.91,246,1647298800"; d="scan'208";a="24031377" Received: from vtuxmail01.tq-net.de ([10.115.0.20]) by mx1.tq-group.com with ESMTP; 23 May 2022 13:05:19 +0200 Received: from steina-w.tq-net.de (unknown [10.123.49.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by vtuxmail01.tq-net.de (Postfix) with ESMTPSA id 35BC2280070; Mon, 23 May 2022 13:05:19 +0200 (CEST) From: Alexander Stein To: Jean Delvare , Guenter Roeck , Jonathan Corbet , Thierry Reding , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Lee Jones Cc: Alexander Stein , linux-hwmon@vger.kernel.org, linux-pwm@vger.kernel.org, Markus Niebel Subject: [PATCH v4 6/6] hwmon: pwm-fan: Remove internal duplicated pwm_state Date: Mon, 23 May 2022 13:05:13 +0200 Message-Id: <20220523110513.407516-7-alexander.stein@ew.tq-group.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> References: <20220523110513.407516-1-alexander.stein@ew.tq-group.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, URIBL_CSS_A autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org Each pwm device has already a pwm_state. Use this one instead of managing an own copy of it. Signed-off-by: Alexander Stein --- drivers/hwmon/pwm-fan.c | 49 +++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index e5d4b3b1cc49..e0ce81cdf5e0 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -40,7 +40,6 @@ struct pwm_fan_ctx { struct mutex lock; struct pwm_device *pwm; - struct pwm_state pwm_state; struct regulator *reg_en; enum pwm_fan_enable_mode enable_mode; bool regulator_enabled; @@ -142,7 +141,7 @@ static int pwm_fan_switch_power(struct pwm_fan_ctx *ctx, bool on) static int pwm_fan_power_on(struct pwm_fan_ctx *ctx) { - struct pwm_state *state = &ctx->pwm_state; + struct pwm_state state; int ret; if (ctx->enabled) @@ -154,8 +153,9 @@ static int pwm_fan_power_on(struct pwm_fan_ctx *ctx) return ret; } - state->enabled = true; - ret = pwm_apply_state(ctx->pwm, state); + pwm_get_state(ctx->pwm, &state); + state.enabled = true; + ret = pwm_apply_state(ctx->pwm, &state); if (ret) { dev_err(ctx->dev, "failed to enable PWM\n"); goto disable_regulator; @@ -172,19 +172,20 @@ static int pwm_fan_power_on(struct pwm_fan_ctx *ctx) static int pwm_fan_power_off(struct pwm_fan_ctx *ctx) { - struct pwm_state *state = &ctx->pwm_state; bool enable_regulator = false; + struct pwm_state state; if (!ctx->enabled) return 0; pwm_fan_enable_mode_2_state(ctx->enable_mode, - state, + &state, &enable_regulator); - state->enabled = false; - state->duty_cycle = 0; - pwm_apply_state(ctx->pwm, state); + pwm_get_state(ctx->pwm, &state); + state.enabled = false; + state.duty_cycle = 0; + pwm_apply_state(ctx->pwm, &state); pwm_fan_switch_power(ctx, enable_regulator); @@ -195,7 +196,7 @@ static int pwm_fan_power_off(struct pwm_fan_ctx *ctx) static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) { - struct pwm_state *state = &ctx->pwm_state; + struct pwm_state state; unsigned long period; int ret = 0; @@ -204,9 +205,10 @@ static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm) /* pwm-fan hard disabled */ return 0; - period = state->period; - state->duty_cycle = DIV_ROUND_UP(pwm * (period - 1), MAX_PWM); - ret = pwm_apply_state(ctx->pwm, state); + pwm_get_state(ctx->pwm, &state); + period = state.period; + state.duty_cycle = DIV_ROUND_UP(pwm * (period - 1), MAX_PWM); + ret = pwm_apply_state(ctx->pwm, &state); if (ret) return ret; ret = pwm_fan_power_on(ctx); @@ -266,15 +268,16 @@ static int pwm_fan_update_enable(struct pwm_fan_ctx *ctx, long val) * Nothing to do if currently enabled */ if (!ctx->enabled) { - struct pwm_state *state = &ctx->pwm_state; bool enable_regulator = false; + struct pwm_state state; - state->duty_cycle = 0; + pwm_get_state(ctx->pwm, &state); + state.duty_cycle = 0; pwm_fan_enable_mode_2_state(val, - state, + &state, &enable_regulator); - pwm_apply_state(ctx->pwm, state); + pwm_apply_state(ctx->pwm, &state); pwm_fan_switch_power(ctx, enable_regulator); pwm_fan_update_state(ctx, 0); } @@ -473,6 +476,7 @@ static int pwm_fan_probe(struct platform_device *pdev) struct thermal_cooling_device *cdev; struct device *dev = &pdev->dev; struct pwm_fan_ctx *ctx; + struct pwm_state state; struct device *hwmon; int ret; const struct hwmon_channel_info **channels; @@ -501,18 +505,25 @@ static int pwm_fan_probe(struct platform_device *pdev) ctx->reg_en = NULL; } - pwm_init_state(ctx->pwm, &ctx->pwm_state); + pwm_init_state(ctx->pwm, &state); /* * set_pwm assumes that MAX_PWM * (period - 1) fits into an unsigned * long. Check this here to prevent the fan running at a too low * frequency. */ - if (ctx->pwm_state.period > ULONG_MAX / MAX_PWM + 1) { + if (state.period > ULONG_MAX / MAX_PWM + 1) { dev_err(dev, "Configured period too big\n"); return -EINVAL; } + /* Apply modified PWM default state */ + ret = pwm_apply_state(ctx->pwm, &state); + if (ret) { + dev_err(dev, "failed to apply initial PWM state: %d\n", ret); + return -EINVAL; + } + ctx->enable_mode = pwm_disable_reg_enable; /*