From patchwork Tue Mar 12 21:46:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= X-Patchwork-Id: 1055775 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44JpSm1XsJz9s70 for ; Wed, 13 Mar 2019 08:46:16 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726396AbfCLVqN (ORCPT ); Tue, 12 Mar 2019 17:46:13 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:35483 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726477AbfCLVqN (ORCPT ); Tue, 12 Mar 2019 17:46:13 -0400 Received: from pty.hi.pengutronix.de ([2001:67c:670:100:1d::c5]) by metis.ext.pengutronix.de with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1h3pDv-0007AS-3n; Tue, 12 Mar 2019 22:46:11 +0100 Received: from ukl by pty.hi.pengutronix.de with local (Exim 4.89) (envelope-from ) id 1h3pDr-0005iI-Cs; Tue, 12 Mar 2019 22:46:07 +0100 From: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= To: Thierry Reding , Heiko Stuebner , Maxime Ripard , Chen-Yu Tsai Cc: linux-pwm@vger.kernel.org, linux-rockchip@lists.infradead.org, kernel@pengutronix.de Subject: [PATCH v2 1/3] pwm: rockchip: Don't update the state for the caller of pwm_apply_state() Date: Tue, 12 Mar 2019 22:46:03 +0100 Message-Id: <20190312214605.10223-2-u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190312214605.10223-1-u.kleine-koenig@pengutronix.de> References: <20190312214605.10223-1-u.kleine-koenig@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::c5 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-pwm@vger.kernel.org Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org The pwm-rockchip driver is one of only two PWM drivers which updates the state for the caller of pwm_apply_state(). This might have surprising results if the caller reuses the values expecting them to still represent the same state. Also note that this feedback was incomplete as the matching struct pwm_device::state wasn't updated and so pwm_get_state still returned the originally requested state. Signed-off-by: Uwe Kleine-König Tested-by: Heiko Stuebner --- drivers/pwm/pwm-rockchip.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c index 4d99d468df09..16186bcd99e0 100644 --- a/drivers/pwm/pwm-rockchip.c +++ b/drivers/pwm/pwm-rockchip.c @@ -215,12 +215,6 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, goto out; } - /* - * Update the state with the real hardware, which can differ a bit - * because of period/duty_cycle approximation. - */ - rockchip_pwm_get_state(chip, pwm, state); - out: clk_disable(pc->pclk); From patchwork Tue Mar 12 21:46:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= X-Patchwork-Id: 1055777 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44JpSn5tKKz9s70 for ; Wed, 13 Mar 2019 08:46:17 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726409AbfCLVqO (ORCPT ); Tue, 12 Mar 2019 17:46:14 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:33955 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726406AbfCLVqO (ORCPT ); Tue, 12 Mar 2019 17:46:14 -0400 Received: from pty.hi.pengutronix.de ([2001:67c:670:100:1d::c5]) by metis.ext.pengutronix.de with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1h3pDv-0007AT-3m; Tue, 12 Mar 2019 22:46:11 +0100 Received: from ukl by pty.hi.pengutronix.de with local (Exim 4.89) (envelope-from ) id 1h3pDr-0005iL-IA; Tue, 12 Mar 2019 22:46:07 +0100 From: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= To: Thierry Reding , Heiko Stuebner , Maxime Ripard , Chen-Yu Tsai Cc: linux-pwm@vger.kernel.org, linux-rockchip@lists.infradead.org, kernel@pengutronix.de Subject: [PATCH v2 2/3] pwm: sun4i: Don't update the state for the caller of pwm_apply_state() Date: Tue, 12 Mar 2019 22:46:04 +0100 Message-Id: <20190312214605.10223-3-u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190312214605.10223-1-u.kleine-koenig@pengutronix.de> References: <20190312214605.10223-1-u.kleine-koenig@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::c5 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-pwm@vger.kernel.org Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org The pwm-sun4i driver is one of only two PWM drivers which updates the state for the caller of pwm_apply_state(). This might have surprising results if the caller reuses the values expecting them to still represent the same state. Also note that this feedback was incomplete as the matching struct pwm_device::state wasn't updated and so pwm_get_state still returned the originally requested state. Signed-off-by: Uwe Kleine-König --- drivers/pwm/pwm-sun4i.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c index 470d4f71e7eb..142a603fe7ea 100644 --- a/drivers/pwm/pwm-sun4i.c +++ b/drivers/pwm/pwm-sun4i.c @@ -193,12 +193,6 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm, *dty = div; *prsclr = prescaler; - div = (u64)pval * NSEC_PER_SEC * *prd; - state->period = DIV_ROUND_CLOSEST_ULL(div, clk_rate); - - div = (u64)pval * NSEC_PER_SEC * *dty; - state->duty_cycle = DIV_ROUND_CLOSEST_ULL(div, clk_rate); - return 0; } From patchwork Tue Mar 12 21:46:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= X-Patchwork-Id: 1055776 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pwm-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44JpSm6mCXz9s4Y for ; Wed, 13 Mar 2019 08:46:16 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726477AbfCLVqO (ORCPT ); Tue, 12 Mar 2019 17:46:14 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:52727 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726409AbfCLVqO (ORCPT ); Tue, 12 Mar 2019 17:46:14 -0400 Received: from pty.hi.pengutronix.de ([2001:67c:670:100:1d::c5]) by metis.ext.pengutronix.de with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1h3pDv-0007AV-3n; Tue, 12 Mar 2019 22:46:11 +0100 Received: from ukl by pty.hi.pengutronix.de with local (Exim 4.89) (envelope-from ) id 1h3pDr-0005iO-O1; Tue, 12 Mar 2019 22:46:07 +0100 From: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= To: Thierry Reding , Heiko Stuebner , Maxime Ripard , Chen-Yu Tsai Cc: linux-pwm@vger.kernel.org, linux-rockchip@lists.infradead.org, kernel@pengutronix.de Subject: [PATCH v2 3/3] pwm: ensure pwm_apply_state() doesn't modify the state argument Date: Tue, 12 Mar 2019 22:46:05 +0100 Message-Id: <20190312214605.10223-4-u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190312214605.10223-1-u.kleine-koenig@pengutronix.de> References: <20190312214605.10223-1-u.kleine-koenig@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::c5 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-pwm@vger.kernel.org Sender: linux-pwm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pwm@vger.kernel.org It is surprising for a PWM consumer when the variable holding the requested state is modified by pwm_apply_state(). Consider for example a driver doing: #define PERIOD 5000000 #define DUTY_LITTLE 10 ... struct pwm_state state = { .period = PERIOD, .duty_cycle = DUTY_LITTLE, .polarity = PWM_POLARITY_NORMAL, .enabled = true, }; pwm_apply_state(mypwm, &state); ... state.duty_cycle = PERIOD / 2; pwm_apply_state(mypwm, &state); For sure the second call to pwm_apply_state() should still have state.period = PERIOD and not something the hardware driver chose for a reason that doesn't necessarily apply to the second call. So declare the state argument as a pointer to a const type and adapt all drivers' .apply callbacks. Signed-off-by: Uwe Kleine-König --- drivers/pwm/core.c | 2 +- drivers/pwm/pwm-atmel-hlcdc.c | 2 +- drivers/pwm/pwm-atmel.c | 2 +- drivers/pwm/pwm-bcm-iproc.c | 2 +- drivers/pwm/pwm-cros-ec.c | 2 +- drivers/pwm/pwm-hibvt.c | 2 +- drivers/pwm/pwm-imx27.c | 2 +- drivers/pwm/pwm-lpss.c | 2 +- drivers/pwm/pwm-meson.c | 2 +- drivers/pwm/pwm-rcar.c | 2 +- drivers/pwm/pwm-rockchip.c | 4 ++-- drivers/pwm/pwm-stm32-lp.c | 2 +- drivers/pwm/pwm-sun4i.c | 4 ++-- drivers/pwm/pwm-zx.c | 2 +- include/linux/pwm.h | 4 ++-- 15 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 3149204567f3..e547c3217fca 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -464,7 +464,7 @@ EXPORT_SYMBOL_GPL(pwm_free); * if the requested config is not achievable, for example, * ->duty_cycle and ->period might be approximated. */ -int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state) +int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state) { int err; diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c index 54c6633d9b5d..20f3feb6ce4a 100644 --- a/drivers/pwm/pwm-atmel-hlcdc.c +++ b/drivers/pwm/pwm-atmel-hlcdc.c @@ -50,7 +50,7 @@ static inline struct atmel_hlcdc_pwm *to_atmel_hlcdc_pwm(struct pwm_chip *chip) } static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c); struct atmel_hlcdc *hlcdc = chip->hlcdc; diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c index a9fd6f0d408c..c185d3d73d4e 100644 --- a/drivers/pwm/pwm-atmel.c +++ b/drivers/pwm/pwm-atmel.c @@ -210,7 +210,7 @@ static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm, } static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip); struct pwm_state cstate; diff --git a/drivers/pwm/pwm-bcm-iproc.c b/drivers/pwm/pwm-bcm-iproc.c index d961a8207b1c..56c38cfae92c 100644 --- a/drivers/pwm/pwm-bcm-iproc.c +++ b/drivers/pwm/pwm-bcm-iproc.c @@ -115,7 +115,7 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm, } static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { unsigned long prescale = IPROC_PWM_PRESCALE_MIN; struct iproc_pwmc *ip = to_iproc_pwmc(chip); diff --git a/drivers/pwm/pwm-cros-ec.c b/drivers/pwm/pwm-cros-ec.c index 98f6ac6cf6ab..db5faa79c33f 100644 --- a/drivers/pwm/pwm-cros-ec.c +++ b/drivers/pwm/pwm-cros-ec.c @@ -93,7 +93,7 @@ static int cros_ec_pwm_get_duty(struct cros_ec_device *ec, u8 index) } static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct cros_ec_pwm_device *ec_pwm = pwm_to_cros_ec_pwm(chip); int duty_cycle; diff --git a/drivers/pwm/pwm-hibvt.c b/drivers/pwm/pwm-hibvt.c index a0b09603d13d..086dfd3850e8 100644 --- a/drivers/pwm/pwm-hibvt.c +++ b/drivers/pwm/pwm-hibvt.c @@ -161,7 +161,7 @@ static void hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, } static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip); diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c index 806130654211..eefc69133fa4 100644 --- a/drivers/pwm/pwm-imx27.c +++ b/drivers/pwm/pwm-imx27.c @@ -205,7 +205,7 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip, } static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { unsigned long period_cycles, duty_cycles, prescale; struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c index 2ac3a2aa9e53..3b7e7ee0da8c 100644 --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c @@ -125,7 +125,7 @@ static inline void pwm_lpss_cond_enable(struct pwm_device *pwm, bool cond) } static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct pwm_lpss_chip *lpwm = to_lpwm(chip); int ret; diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c index c1ed641b3e26..72def8772593 100644 --- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -292,7 +292,7 @@ static void meson_pwm_disable(struct meson_pwm *meson, unsigned int id) } static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); struct meson_pwm *meson = to_meson_pwm(chip); diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c index cfe7dd1b448e..91ab1889eb66 100644 --- a/drivers/pwm/pwm-rcar.c +++ b/drivers/pwm/pwm-rcar.c @@ -158,7 +158,7 @@ static void rcar_pwm_disable(struct rcar_pwm_chip *rp) } static int rcar_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct rcar_pwm_chip *rp = to_rcar_pwm_chip(chip); struct pwm_state cur_state; diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c index 16186bcd99e0..1501541d801e 100644 --- a/drivers/pwm/pwm-rockchip.c +++ b/drivers/pwm/pwm-rockchip.c @@ -102,7 +102,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip, } static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); unsigned long period, duty; @@ -186,7 +186,7 @@ static int rockchip_pwm_enable(struct pwm_chip *chip, } static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); struct pwm_state curstate; diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c index 0059b24cfdc3..11c5295c6a86 100644 --- a/drivers/pwm/pwm-stm32-lp.c +++ b/drivers/pwm/pwm-stm32-lp.c @@ -31,7 +31,7 @@ static inline struct stm32_pwm_lp *to_stm32_pwm_lp(struct pwm_chip *chip) #define STM32_LPTIM_MAX_PRESCALER 128 static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip); unsigned long long prd, div, dty; diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c index 142a603fe7ea..52dace9f739e 100644 --- a/drivers/pwm/pwm-sun4i.c +++ b/drivers/pwm/pwm-sun4i.c @@ -146,7 +146,7 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip, } static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm, - struct pwm_state *state, + const struct pwm_state *state, u32 *dty, u32 *prd, unsigned int *prsclr) { u64 clk_rate, div = 0; @@ -197,7 +197,7 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm, } static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip); struct pwm_state cstate; diff --git a/drivers/pwm/pwm-zx.c b/drivers/pwm/pwm-zx.c index 5d27c16edfb1..d6da939a2e57 100644 --- a/drivers/pwm/pwm-zx.c +++ b/drivers/pwm/pwm-zx.c @@ -151,7 +151,7 @@ static int zx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, } static int zx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state) + const struct pwm_state *state) { struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip); struct pwm_state cstate; diff --git a/include/linux/pwm.h b/include/linux/pwm.h index b628abfffacc..7525787985bb 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -262,7 +262,7 @@ struct pwm_ops { int (*capture)(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_capture *result, unsigned long timeout); int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm, - struct pwm_state *state); + const struct pwm_state *state); void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state); struct module *owner; @@ -316,7 +316,7 @@ struct pwm_capture { /* PWM user APIs */ struct pwm_device *pwm_request(int pwm_id, const char *label); void pwm_free(struct pwm_device *pwm); -int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state); +int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state); int pwm_adjust_config(struct pwm_device *pwm); /**