summaryrefslogtreecommitdiff
path: root/drivers/soc/imx
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2021-05-10 07:00:39 +0300
committerShawn Guo <shawnguo@kernel.org>2021-05-23 05:58:10 +0300
commitc0ce75395f8d088ba56dcec3218c628ef2bb6d73 (patch)
treeff2a0e7dad762f6ca14e2298536610cbd7d2eee5 /drivers/soc/imx
parent1382eb1967d74fb40c3c9e8c6f6030c4c0ecc040 (diff)
downloadlinux-c0ce75395f8d088ba56dcec3218c628ef2bb6d73.tar.xz
soc: imx: gpcv2: allow domains without power-sequence control
Some of the PGC domains only control the handshake with the ADB400 and don't have any power sequence controls. Make such domains work by allowing the pxx and map bits to be empty and skip all actions using those controls. Tested-by: Frieder Schrempf <frieder.schrempf@kontron.de> Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de> Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Peng Fan <peng.fan@nxp.com> Signed-off-by: Shawn Guo <shawnguo@kernel.org>
Diffstat (limited to 'drivers/soc/imx')
-rw-r--r--drivers/soc/imx/gpcv2.c89
1 files changed, 49 insertions, 40 deletions
diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index 800287abdbea..fdf759a7c865 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -163,24 +163,27 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
goto out_regulator_disable;
}
- /* request the domain to power up */
- regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ,
- domain->bits.pxx, domain->bits.pxx);
- /*
- * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
- * for PUP_REQ/PDN_REQ bit to be cleared
- */
- ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PGC_SW_PUP_REQ,
- reg_val, !(reg_val & domain->bits.pxx),
- 0, USEC_PER_MSEC);
- if (ret) {
- dev_err(domain->dev, "failed to command PGC\n");
- goto out_clk_disable;
- }
+ if (domain->bits.pxx) {
+ /* request the domain to power up */
+ regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ,
+ domain->bits.pxx, domain->bits.pxx);
+ /*
+ * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
+ * for PUP_REQ/PDN_REQ bit to be cleared
+ */
+ ret = regmap_read_poll_timeout(domain->regmap,
+ GPC_PU_PGC_SW_PUP_REQ, reg_val,
+ !(reg_val & domain->bits.pxx),
+ 0, USEC_PER_MSEC);
+ if (ret) {
+ dev_err(domain->dev, "failed to command PGC\n");
+ goto out_clk_disable;
+ }
- /* disable power control */
- regmap_clear_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
- GPC_PGC_CTRL_PCR);
+ /* disable power control */
+ regmap_clear_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
+ GPC_PGC_CTRL_PCR);
+ }
/* request the ADB400 to power up */
if (domain->bits.hskreq) {
@@ -245,23 +248,26 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)
}
}
- /* enable power control */
- regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
- GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR);
-
- /* request the domain to power down */
- regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PDN_REQ,
- domain->bits.pxx, domain->bits.pxx);
- /*
- * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
- * for PUP_REQ/PDN_REQ bit to be cleared
- */
- ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PGC_SW_PDN_REQ,
- reg_val, !(reg_val & domain->bits.pxx),
- 0, USEC_PER_MSEC);
- if (ret) {
- dev_err(domain->dev, "failed to command PGC\n");
- goto out_clk_disable;
+ if (domain->bits.pxx) {
+ /* enable power control */
+ regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
+ GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR);
+
+ /* request the domain to power down */
+ regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PDN_REQ,
+ domain->bits.pxx, domain->bits.pxx);
+ /*
+ * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
+ * for PUP_REQ/PDN_REQ bit to be cleared
+ */
+ ret = regmap_read_poll_timeout(domain->regmap,
+ GPC_PU_PGC_SW_PDN_REQ, reg_val,
+ !(reg_val & domain->bits.pxx),
+ 0, USEC_PER_MSEC);
+ if (ret) {
+ dev_err(domain->dev, "failed to command PGC\n");
+ goto out_clk_disable;
+ }
}
/* Disable reset clocks for all devices in the domain */
@@ -536,8 +542,9 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
pm_runtime_enable(domain->dev);
- regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
- domain->bits.map, domain->bits.map);
+ if (domain->bits.map)
+ regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
+ domain->bits.map, domain->bits.map);
ret = pm_genpd_init(&domain->genpd, NULL, true);
if (ret) {
@@ -557,8 +564,9 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
out_genpd_remove:
pm_genpd_remove(&domain->genpd);
out_domain_unmap:
- regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
- domain->bits.map, 0);
+ if (domain->bits.map)
+ regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
+ domain->bits.map, 0);
pm_runtime_disable(domain->dev);
return ret;
@@ -571,8 +579,9 @@ static int imx_pgc_domain_remove(struct platform_device *pdev)
of_genpd_del_provider(domain->dev->of_node);
pm_genpd_remove(&domain->genpd);
- regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
- domain->bits.map, 0);
+ if (domain->bits.map)
+ regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
+ domain->bits.map, 0);
pm_runtime_disable(domain->dev);