Patch "soc: qcom: rpmhpd: Make power_on actually enable the domain" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    soc: qcom: rpmhpd: Make power_on actually enable the domain

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     soc-qcom-rpmhpd-make-power_on-actually-enable-the-do.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit d6b7c2ea1dccdcfe4f32484deab671516083bd23
Author: Bjorn Andersson <bjorn.andersson@xxxxxxxxxx>
Date:   Mon Oct 4 20:37:32 2021 -0700

    soc: qcom: rpmhpd: Make power_on actually enable the domain
    
    [ Upstream commit e3e56c050ab6e3f1bd811f0787f50709017543e4 ]
    
    The general expectation is that powering on a power-domain should make
    the power domain deliver some power, and if a specific performance state
    is needed further requests has to be made.
    
    But in contrast with other power-domain implementations (e.g. rpmpd) the
    RPMh does not have an interface to enable the power, so the driver has
    to vote for a particular corner (performance level) in rpmh_power_on().
    
    But the corner is never initialized, so a typical request to simply
    enable the power domain would not actually turn on the hardware. Further
    more, when no more clients vote for a performance state (i.e. the
    aggregated vote is 0) the power domain would be turned off.
    
    Fix both of these issues by always voting for a corner with non-zero
    value, when the power domain is enabled.
    
    The tracking of the lowest non-zero corner is performed to handle the
    corner case if there's ever a domain with a non-zero lowest corner, in
    which case both rpmh_power_on() and rpmh_rpmhpd_set_performance_state()
    would be allowed to use this lowest corner.
    
    Fixes: 279b7e8a62cc ("soc: qcom: rpmhpd: Add RPMh power domain driver")
    Signed-off-by: Bjorn Andersson <bjorn.andersson@xxxxxxxxxx>
    Reviewed-by: Stephen Boyd <swboyd@xxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20211005033732.2284447-1-bjorn.andersson@xxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
index e7cb40144f9b1..436ec79122ed2 100644
--- a/drivers/soc/qcom/rpmhpd.c
+++ b/drivers/soc/qcom/rpmhpd.c
@@ -30,6 +30,7 @@
  * @active_only:	True if it represents an Active only peer
  * @corner:		current corner
  * @active_corner:	current active corner
+ * @enable_corner:	lowest non-zero corner
  * @level:		An array of level (vlvl) to corner (hlvl) mappings
  *			derived from cmd-db
  * @level_count:	Number of levels supported by the power domain. max
@@ -47,6 +48,7 @@ struct rpmhpd {
 	const bool	active_only;
 	unsigned int	corner;
 	unsigned int	active_corner;
+	unsigned int	enable_corner;
 	u32		level[RPMH_ARC_MAX_LEVELS];
 	size_t		level_count;
 	bool		enabled;
@@ -295,13 +297,13 @@ static int rpmhpd_aggregate_corner(struct rpmhpd *pd, unsigned int corner)
 static int rpmhpd_power_on(struct generic_pm_domain *domain)
 {
 	struct rpmhpd *pd = domain_to_rpmhpd(domain);
-	int ret = 0;
+	unsigned int corner;
+	int ret;
 
 	mutex_lock(&rpmhpd_lock);
 
-	if (pd->corner)
-		ret = rpmhpd_aggregate_corner(pd, pd->corner);
-
+	corner = max(pd->corner, pd->enable_corner);
+	ret = rpmhpd_aggregate_corner(pd, corner);
 	if (!ret)
 		pd->enabled = true;
 
@@ -346,6 +348,10 @@ static int rpmhpd_set_performance_state(struct generic_pm_domain *domain,
 		i--;
 
 	if (pd->enabled) {
+		/* Ensure that the domain isn't turn off */
+		if (i < pd->enable_corner)
+			i = pd->enable_corner;
+
 		ret = rpmhpd_aggregate_corner(pd, i);
 		if (ret)
 			goto out;
@@ -382,6 +388,10 @@ static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd)
 	for (i = 0; i < rpmhpd->level_count; i++) {
 		rpmhpd->level[i] = buf[i];
 
+		/* Remember the first corner with non-zero level */
+		if (!rpmhpd->level[rpmhpd->enable_corner] && rpmhpd->level[i])
+			rpmhpd->enable_corner = i;
+
 		/*
 		 * The AUX data may be zero padded.  These 0 valued entries at
 		 * the end of the map must be ignored.



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux