Linux PWM subsystem development
 help / color / mirror / Atom feed
From: Andre Przywara <andre.przywara-5wv7dgnIgG8@public.gmane.org>
To: Thierry Reding
	<thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Maxime Ripard
	<maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org>,
	Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
Cc: linux-pwm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH 3/5] pwm: sun4i: Introduce (optional) reset support
Date: Wed,  7 Mar 2018 02:07:17 +0000	[thread overview]
Message-ID: <20180307020719.6675-4-andre.przywara@arm.com> (raw)
In-Reply-To: <20180307020719.6675-1-andre.przywara-5wv7dgnIgG8@public.gmane.org>

While the PWM IP in the Allwinner H6 SoC is fully compatible to those
used in older SoCs (H3, A64), it features a dedicated reset line which
needs to be de-asserted.
Add support for an optional "resets" DT property in our pwm-sun4i probe
routine, and assert and de-assert the reset line, where needed.
This allows to enable PWM support on the H6.

Signed-off-by: Andre Przywara <andre.przywara-5wv7dgnIgG8@public.gmane.org>
---
 drivers/pwm/pwm-sun4i.c | 34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 078172dee462..4eefb27fe80b 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -17,6 +17,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
+#include <linux/reset.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/time.h>
@@ -79,6 +80,7 @@ struct sun4i_pwm_data {
 struct sun4i_pwm_chip {
 	struct pwm_chip chip;
 	struct clk *clk;
+	struct reset_control *reset;
 	void __iomem *base;
 	spinlock_t ctrl_lock;
 	const struct sun4i_pwm_data *data;
@@ -206,7 +208,7 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
 	struct pwm_state cstate;
 	u32 ctrl;
-	int ret;
+	int ret = 0;
 	unsigned int delay_us;
 	unsigned long now;
 
@@ -218,6 +220,18 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			dev_err(chip->dev, "failed to enable PWM clock\n");
 			return ret;
 		}
+
+		/* Deassert reset if we have a reset control */
+		if (sun4i_pwm->reset) {
+			ret = reset_control_deassert(sun4i_pwm->reset);
+			if (ret) {
+				dev_err(chip->dev,
+					"Cannot deassert reset control\n");
+				clk_disable_unprepare(sun4i_pwm->clk);
+
+				return ret;
+			}
+		}
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
@@ -234,7 +248,8 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			dev_err(chip->dev, "period exceeds the maximum value\n");
 			spin_unlock(&sun4i_pwm->ctrl_lock);
 			if (!cstate.enabled)
-				clk_disable_unprepare(sun4i_pwm->clk);
+				goto out_disable;
+
 			return ret;
 		}
 
@@ -274,10 +289,8 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	if (state->enabled)
 		return 0;
 
-	if (!sun4i_pwm->needs_delay[pwm->hwpwm]) {
-		clk_disable_unprepare(sun4i_pwm->clk);
-		return 0;
-	}
+	if (!sun4i_pwm->needs_delay[pwm->hwpwm])
+		goto out_disable;
 
 	/* We need a full period to elapse before disabling the channel. */
 	now = jiffies;
@@ -299,9 +312,12 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 
+out_disable:
 	clk_disable_unprepare(sun4i_pwm->clk);
+	if (sun4i_pwm->reset)
+		reset_control_assert(sun4i_pwm->reset);
 
-	return 0;
+	return ret;
 }
 
 static const struct pwm_ops sun4i_pwm_ops = {
@@ -370,6 +386,10 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 	if (IS_ERR(pwm->clk))
 		return PTR_ERR(pwm->clk);
 
+	pwm->reset = devm_reset_control_get_optional(&pdev->dev, NULL);
+	if (IS_ERR(pwm->reset))
+		return PTR_ERR(pwm->reset);
+
 	pwm->chip.dev = &pdev->dev;
 	pwm->chip.ops = &sun4i_pwm_ops;
 	pwm->chip.base = -1;
-- 
2.14.1

  parent reply	other threads:[~2018-03-07  2:07 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-07  2:07 [PATCH 0/5] drivers: pwm: sun4i: Improve support for A64 and H6 SoCs Andre Przywara
     [not found] ` <20180307020719.6675-1-andre.przywara-5wv7dgnIgG8@public.gmane.org>
2018-03-07  2:07   ` [PATCH 1/5] pwm: sun4i: drop unused .has_rdy member Andre Przywara
2018-03-07  7:40     ` Maxime Ripard
2018-03-07  2:07   ` [PATCH 2/5] pwm: sun4i: simplify controller mapping Andre Przywara
2018-03-07  7:44     ` Maxime Ripard
2018-03-07  2:07   ` Andre Przywara [this message]
2018-03-07  7:45     ` [PATCH 3/5] pwm: sun4i: Introduce (optional) reset support Maxime Ripard
     [not found]       ` <20180307074516.dbak7ztkua4p7mr5-ZC1Zs529Oq4@public.gmane.org>
2018-03-13 14:05         ` Andre Przywara
2018-03-13 15:32           ` Maxime Ripard
2018-03-07  2:07   ` [PATCH 4/5] dt-bindings: pwm: sunxi: add new compatible strings Andre Przywara
     [not found]     ` <20180307020719.6675-5-andre.przywara-5wv7dgnIgG8@public.gmane.org>
2018-03-08  2:08       ` Rob Herring
2018-03-08  9:09         ` Andre Przywara
     [not found]           ` <9431a141-8b9c-9743-0907-8f0720df34a2-5wv7dgnIgG8@public.gmane.org>
2018-03-08 14:37             ` Rob Herring
     [not found]               ` <CAL_Jsq+e8uRm0gi1dn3Ln-b37SC9WGw5aWPaBKoRA2vi-==j6A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-03-08 15:27                 ` Andre Przywara
2018-03-07  2:07   ` [PATCH 5/5] dts: sunxi: A64: Add PWM controllers Andre Przywara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180307020719.6675-4-andre.przywara@arm.com \
    --to=andre.przywara-5wv7dgnigg8@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-pwm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org \
    --cc=maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org \
    --cc=thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=wens-jdAy2FN1RRM@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox