lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Fri,  3 Nov 2017 16:43:24 +0100
From:   Neil Armstrong <narmstrong@...libre.com>
To:     khilman@...libre.com, carlo@...one.org
Cc:     Neil Armstrong <narmstrong@...libre.com>, linux-pm@...r.kernel.org,
        linux-amlogic@...ts.infradead.org,
        linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org
Subject: [PATCH] soc: amlogic: meson-gx-pwrc-vpu: fix power-off when powered by bootloader

In the case the VPU power domain has been powered on by the bootloader
and no driver are attached to this power domain, the genpd will power it
off after a certain amount of time, but the clocks hasn't been enabled
by the kernel itself and the power-off will trigger some faults.
This patch enable the clocks to have a coherent state for an eventual
poweroff and switches to the pm_domain_always_on_gov governor.

Fixes: 75fcb5ca4b46 ("soc: amlogic: add Meson GX VPU Domains driver")
Signed-off-by: Neil Armstrong <narmstrong@...libre.com>
---
 drivers/soc/amlogic/meson-gx-pwrc-vpu.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c
index bf5190b..2bdeebc 100644
--- a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c
+++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c
@@ -34,7 +34,6 @@ struct meson_gx_pwrc_vpu {
 	struct reset_control *rstc;
 	struct clk *vpu_clk;
 	struct clk *vapb_clk;
-	bool powered;
 };
 
 static inline
@@ -78,8 +77,6 @@ static int meson_gx_pwrc_vpu_power_off(struct generic_pm_domain *genpd)
 	clk_disable_unprepare(pd->vpu_clk);
 	clk_disable_unprepare(pd->vapb_clk);
 
-	pd->powered = false;
-
 	return 0;
 }
 
@@ -91,7 +88,11 @@ static int meson_gx_pwrc_vpu_setup_clk(struct meson_gx_pwrc_vpu *pd)
 	if (ret)
 		return ret;
 
-	return clk_prepare_enable(pd->vapb_clk);
+	ret = clk_prepare_enable(pd->vapb_clk);
+	if (ret)
+		clk_disable_unprepare(pd->vpu_clk);
+
+	return ret;
 }
 
 static int meson_gx_pwrc_vpu_power_on(struct generic_pm_domain *genpd)
@@ -139,8 +140,6 @@ static int meson_gx_pwrc_vpu_power_on(struct generic_pm_domain *genpd)
 	if (ret)
 		return ret;
 
-	pd->powered = true;
-
 	return 0;
 }
 
@@ -167,6 +166,8 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev)
 	struct reset_control *rstc;
 	struct clk *vpu_clk;
 	struct clk *vapb_clk;
+	bool powered_off;
+	int ret;
 
 	regmap_ao = syscon_node_to_regmap(of_get_parent(pdev->dev.of_node));
 	if (IS_ERR(regmap_ao)) {
@@ -205,8 +206,17 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev)
 	vpu_hdmi_pd.vpu_clk = vpu_clk;
 	vpu_hdmi_pd.vapb_clk = vapb_clk;
 
-	pm_genpd_init(&vpu_hdmi_pd.genpd, &simple_qos_governor,
-		      meson_gx_pwrc_vpu_get_power(&vpu_hdmi_pd));
+	powered_off = meson_gx_pwrc_vpu_get_power(&vpu_hdmi_pd);
+
+	/* If already powered, sync the clock states */
+	if (!powered_off) {
+		ret = meson_gx_pwrc_vpu_setup_clk(&vpu_hdmi_pd);
+		if (ret)
+			return ret;
+	}
+
+	pm_genpd_init(&vpu_hdmi_pd.genpd, &pm_domain_always_on_gov,
+		      powered_off);
 
 	return of_genpd_add_provider_simple(pdev->dev.of_node,
 					    &vpu_hdmi_pd.genpd);
@@ -214,8 +224,7 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev)
 
 static void meson_gx_pwrc_vpu_shutdown(struct platform_device *pdev)
 {
-	if (vpu_hdmi_pd.powered)
-		meson_gx_pwrc_vpu_power_off(&vpu_hdmi_pd.genpd);
+	meson_gx_pwrc_vpu_power_off(&vpu_hdmi_pd.genpd);
 }
 
 static const struct of_device_id meson_gx_pwrc_vpu_match_table[] = {
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ