Received: by 2002:a25:824b:0:0:0:0:0 with SMTP id d11csp7936927ybn; Tue, 1 Oct 2019 00:05:56 -0700 (PDT) X-Google-Smtp-Source: APXvYqx2KLaJPja2Cxzy+HEBFoMtTASo40YB8UX4xVuzi3zbZOO/Ag5ebqq2ohtMQJCJfIB3CAIG X-Received: by 2002:a17:907:215a:: with SMTP id rk26mr22615674ejb.49.1569913555978; Tue, 01 Oct 2019 00:05:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569913555; cv=none; d=google.com; s=arc-20160816; b=IfwEynVlP/9mAOfWs+uZ6Vi++GD8fPW/Lz1pAFReYrUB+nbHc1lrBkGf46fYJDehCa qgcMbcneBdot7vlmQq+tGr2A9sOlNptt1TzzLqm2yle7h1NsOivkVP7IIUzoubh05agd rWIS+JgXuhlkW6rVt85I/t1GMLr6JHCu26pr4QT1DXpsY05QrLJHguZAjkk5aZoYsl4V 1DrWYapPac8pqTwAhenILMYWsaa8dq7MVe87v9SVU3ymJIumPuYz8sjuZiqgax6k9Xa6 TulhQfLS9c0CS+WrjtBTeW3Ut8bXXVR1e99tpt5zwmaOuvBGA5OgGxJYlI9Y+plDYYLL wVzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-transfer-encoding:content-disposition:mime-version :references:message-id:subject:cc:to:from:date; bh=pwF72aLx8OO0KkCD5GEA38VeiRdPmpBS4sI1kzaNwAc=; b=WJV0ENMLY26c240pniK8CbfdVxl9LcCWF14uw3v4gK8ZgKfuJteIONwstGXZgx/U2V RHGCDdzS6Hb37NBNcfhKXgXbASwUTPtVZW3Ae8YWOrIp/hQhDdxbutyIlWH5jmLb+N6q uHY9oXScPuNF3NR7JnxasgAUpDduLohq+LGHkyn4eKPQPNhcnB/160hCAHE8NCPKoLIK jYRECXw3c47Rj+MgDNa+eXLVUWLNA9LmSQ8PG2ro9EO9j+1kgakyQ1kQfN4XOzKx9r3+ LR/H/OOAQQ6rCyfQiFUcsOE9J9hIhvdsnJ2dkhx+TDmmGQev6TpCWdoa1L6zaerD9Nsa vwaw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v12si8875094edf.212.2019.10.01.00.05.31; Tue, 01 Oct 2019 00:05:55 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732727AbfJAHFE (ORCPT + 99 others); Tue, 1 Oct 2019 03:05:04 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:32781 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725777AbfJAHFE (ORCPT ); Tue, 1 Oct 2019 03:05:04 -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.92) (envelope-from ) id 1iFCDQ-0003FK-Mn; Tue, 01 Oct 2019 09:04:56 +0200 Received: from ukl by pty.hi.pengutronix.de with local (Exim 4.89) (envelope-from ) id 1iFCDK-0006R1-HW; Tue, 01 Oct 2019 09:04:50 +0200 Date: Tue, 1 Oct 2019 09:04:50 +0200 From: Uwe =?iso-8859-1?Q?Kleine-K=F6nig?= To: Fabrice Gasnier Cc: thierry.reding@gmail.com, robh+dt@kernel.org, alexandre.torgue@st.com, mark.rutland@arm.com, mcoquelin.stm32@gmail.com, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org, benjamin.gaignard@st.com, linux-stm32@st-md-mailman.stormreply.com Subject: Re: [PATCH 2/2] pwm: stm32: add power management support Message-ID: <20191001070450.4zogfryzo7a5ssbd@pengutronix.de> References: <1569857951-20007-1-git-send-email-fabrice.gasnier@st.com> <1569857951-20007-3-git-send-email-fabrice.gasnier@st.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1569857951-20007-3-git-send-email-fabrice.gasnier@st.com> User-Agent: NeoMutt/20170113 (1.7.2) 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-kernel@vger.kernel.org Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hello Fabrice, On Mon, Sep 30, 2019 at 05:39:11PM +0200, Fabrice Gasnier wrote: > Add suspend/resume PM sleep ops. When going to low power, enforce the PWM > channel isn't active. Let the PWM consumers disable it during their own > suspend sequence, see [1]. So, perform a check here, and handle the > pinctrl states. Also restore the break inputs upon resume, as registers > content may be lost when going to low power mode. > > [1] https://lkml.org/lkml/2019/2/5/770 > > Signed-off-by: Fabrice Gasnier > --- > drivers/pwm/pwm-stm32.c | 82 +++++++++++++++++++++++++++++++++++++------------ > 1 file changed, 62 insertions(+), 20 deletions(-) > > diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c > index 740e2de..9bcd73a 100644 > --- a/drivers/pwm/pwm-stm32.c > +++ b/drivers/pwm/pwm-stm32.c > @@ -12,6 +12,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -19,6 +20,12 @@ > #define CCMR_CHANNEL_MASK 0xFF > #define MAX_BREAKINPUT 2 > > +struct stm32_breakinput { > + u32 index; > + u32 level; > + u32 filter; > +}; > + > struct stm32_pwm { > struct pwm_chip chip; > struct mutex lock; /* protect pwm config/enable */ > @@ -26,15 +33,11 @@ struct stm32_pwm { > struct regmap *regmap; > u32 max_arr; > bool have_complementary_output; > + struct stm32_breakinput breakinput[MAX_BREAKINPUT]; > + unsigned int nbreakinput; > u32 capture[4] ____cacheline_aligned; /* DMA'able buffer */ > }; > > -struct stm32_breakinput { > - u32 index; > - u32 level; > - u32 filter; > -}; > - > static inline struct stm32_pwm *to_stm32_pwm_dev(struct pwm_chip *chip) > { > return container_of(chip, struct stm32_pwm, chip); > @@ -512,15 +515,27 @@ static int stm32_pwm_set_breakinput(struct stm32_pwm *priv, > return (bdtr & bke) ? 0 : -EINVAL; > } > > -static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv, > +static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv) > +{ > + int i, ret = 0; > + > + for (i = 0; i < priv->nbreakinput && !ret; i++) { > + ret = stm32_pwm_set_breakinput(priv, > + priv->breakinput[i].index, > + priv->breakinput[i].level, > + priv->breakinput[i].filter); > + } > + > + return ret; > +} Can you explain what the effect of this function is? This is something that is lost during suspend? I wonder why the patch is so big. There are some rearrangements that should have no effect and I think it would be beneficial for reviewability to split this patch in a patch that only does the restructuring and than on top of that add the PM stuff. > + > +static int stm32_pwm_probe_breakinputs(struct stm32_pwm *priv, > struct device_node *np) > { > - struct stm32_breakinput breakinput[MAX_BREAKINPUT]; > - int nb, ret, i, array_size; > + int nb, ret, array_size; > > nb = of_property_count_elems_of_size(np, "st,breakinput", > sizeof(struct stm32_breakinput)); > - > /* > * Because "st,breakinput" parameter is optional do not make probe > * failed if it doesn't exist. > @@ -531,20 +546,14 @@ static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv, > if (nb > MAX_BREAKINPUT) > return -EINVAL; > > + priv->nbreakinput = nb; > array_size = nb * sizeof(struct stm32_breakinput) / sizeof(u32); > ret = of_property_read_u32_array(np, "st,breakinput", > - (u32 *)breakinput, array_size); > + (u32 *)priv->breakinput, array_size); > if (ret) > return ret; > > - for (i = 0; i < nb && !ret; i++) { > - ret = stm32_pwm_set_breakinput(priv, > - breakinput[i].index, > - breakinput[i].level, > - breakinput[i].filter); > - } > - > - return ret; > + return stm32_pwm_apply_breakinputs(priv); > } > > static void stm32_pwm_detect_complementary(struct stm32_pwm *priv) > @@ -614,7 +623,7 @@ static int stm32_pwm_probe(struct platform_device *pdev) > if (!priv->regmap || !priv->clk) > return -EINVAL; > > - ret = stm32_pwm_apply_breakinputs(priv, np); > + ret = stm32_pwm_probe_breakinputs(priv, np); > if (ret) > return ret; > > @@ -647,6 +656,38 @@ static int stm32_pwm_remove(struct platform_device *pdev) > return 0; > } > > +static int __maybe_unused stm32_pwm_suspend(struct device *dev) > +{ > + struct stm32_pwm *priv = dev_get_drvdata(dev); > + struct pwm_state state; > + unsigned int i; > + > + for (i = 0; i < priv->chip.npwm; i++) { > + pwm_get_state(&priv->chip.pwms[i], &state); pwm_get_state is a function designed to be used by PWM consumers. I would prefer to check the hardware registers here instead. What if there is no consumer and the PWM just happens to be enabled by the bootloader? Or is this too minor an issue to be worth consideration? Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-K?nig | Industrial Linux Solutions | http://www.pengutronix.de/ |