Merge branch 'CR_2248_PMU_walker.chen' into 'jh7110-5.15.y-devel'

CR_2248_PMU_515: Fix some power domain can not be disabled

See merge request sdk/linux!515
This commit is contained in:
andy.hu 2022-09-30 03:44:05 +00:00
commit 323a02034d
2 changed files with 27 additions and 6 deletions

0
drivers/soc/starfive/Kconfig Executable file → Normal file
View file

33
drivers/soc/starfive/jh7110_pmu.c Executable file → Normal file
View file

@ -7,6 +7,7 @@
#include <dt-bindings/power/jh7110-power.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
@ -50,6 +51,9 @@
PMU_INT_HW_REQ | \
PMU_INT_FAIL_MASK)
#define DELAY_US 10
#define TIMEOUT_US 100000
struct jh7110_power_dev {
struct generic_pm_domain genpd;
struct jh7110_pmu *power;
@ -112,13 +116,14 @@ static int jh7110_pmu_set_state(struct jh7110_power_dev *pmd, bool on)
if (!pmd->mask)
return -EINVAL;
ret = jh7110_pmu_get_state(pmd, &is_on);
if (ret)
dev_info(pmu->pdev, "unable to get current state for %s\n",
pmd->genpd.name);
if (is_on == on) {
dev_info(pmu->pdev, "pm domain is already %sable status.\n",
on ? "en" : "dis");
dev_info(pmu->pdev, "pm domain [%s] is already %sable status.\n",
pmd->genpd.name, on ? "en" : "dis");
return 0;
}
@ -134,9 +139,7 @@ static int jh7110_pmu_set_state(struct jh7110_power_dev *pmd, bool on)
encourage_hi = SW_MODE_ENCOURAGE_DIS_HI;
}
val = __raw_readl(pmu->base + mode);
val |= pmd->mask;
__raw_writel(val, pmu->base + mode);
__raw_writel(pmd->mask, pmu->base + mode);
/* write SW_ENCOURAGE to make the configuration take effect */
__raw_writel(SW_MODE_ENCOURAGE_ON, pmu->base + SW_ENCOURAGE);
@ -145,6 +148,24 @@ static int jh7110_pmu_set_state(struct jh7110_power_dev *pmd, bool on)
spin_unlock_irqrestore(&pmu->lock, flags);
if (on) {
ret = readl_poll_timeout_atomic(pmu->base + CURR_POWER_MODE, val,
val & pmd->mask, DELAY_US,
TIMEOUT_US);
if (ret) {
dev_err(pmu->pdev, "%s power_on failed", pmd->genpd.name);
return -ETIMEDOUT;
}
} else {
ret = readl_poll_timeout_atomic(pmu->base + CURR_POWER_MODE, val,
!(val & pmd->mask), DELAY_US,
TIMEOUT_US);
if (ret) {
dev_err(pmu->pdev, "%s power_off failed", pmd->genpd.name);
return -ETIMEDOUT;
}
}
return 0;
}
@ -354,6 +375,6 @@ static struct platform_driver jh7110_pmu_driver = {
};
builtin_platform_driver(jh7110_pmu_driver);
MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
MODULE_AUTHOR("Walker Chen <walker.chen@linux.starfivetech.com>");
MODULE_DESCRIPTION("Starfive JH7110 Power Domain Driver");
MODULE_LICENSE("GPL");