Skip to content

Commit 1b77183

Browse files
lumagbebarino
authored andcommitted
clk: qcom: gdsc: enable optional power domain support
On sm8250 dispcc and videocc registers are powered up by the MMCX power domain. Currently we use a regulator to enable this domain on demand, however this has some consequences, as genpd code is not reentrant. Make gdsc code also use pm_runtime calls to ensure that registers are accessible during the gdsc_enable/gdsc_disable operations. Signed-off-by: Dmitry Baryshkov <[email protected]> Reviewed-by: Bjorn Andersson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent a91c483 commit 1b77183

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

drivers/clk/qcom/gdsc.c

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/kernel.h>
1212
#include <linux/ktime.h>
1313
#include <linux/pm_domain.h>
14+
#include <linux/pm_runtime.h>
1415
#include <linux/regmap.h>
1516
#include <linux/regulator/consumer.h>
1617
#include <linux/reset-controller.h>
@@ -50,6 +51,22 @@ enum gdsc_status {
5051
GDSC_ON
5152
};
5253

54+
static int gdsc_pm_runtime_get(struct gdsc *sc)
55+
{
56+
if (!sc->dev)
57+
return 0;
58+
59+
return pm_runtime_resume_and_get(sc->dev);
60+
}
61+
62+
static int gdsc_pm_runtime_put(struct gdsc *sc)
63+
{
64+
if (!sc->dev)
65+
return 0;
66+
67+
return pm_runtime_put_sync(sc->dev);
68+
}
69+
5370
/* Returns 1 if GDSC status is status, 0 if not, and < 0 on error */
5471
static int gdsc_check_status(struct gdsc *sc, enum gdsc_status status)
5572
{
@@ -232,9 +249,8 @@ static void gdsc_retain_ff_on(struct gdsc *sc)
232249
regmap_update_bits(sc->regmap, sc->gdscr, mask, mask);
233250
}
234251

235-
static int gdsc_enable(struct generic_pm_domain *domain)
252+
static int _gdsc_enable(struct gdsc *sc)
236253
{
237-
struct gdsc *sc = domain_to_gdsc(domain);
238254
int ret;
239255

240256
if (sc->pwrsts == PWRSTS_ON)
@@ -290,11 +306,22 @@ static int gdsc_enable(struct generic_pm_domain *domain)
290306
return 0;
291307
}
292308

293-
static int gdsc_disable(struct generic_pm_domain *domain)
309+
static int gdsc_enable(struct generic_pm_domain *domain)
294310
{
295311
struct gdsc *sc = domain_to_gdsc(domain);
296312
int ret;
297313

314+
ret = gdsc_pm_runtime_get(sc);
315+
if (ret)
316+
return ret;
317+
318+
return _gdsc_enable(sc);
319+
}
320+
321+
static int _gdsc_disable(struct gdsc *sc)
322+
{
323+
int ret;
324+
298325
if (sc->pwrsts == PWRSTS_ON)
299326
return gdsc_assert_reset(sc);
300327

@@ -329,6 +356,18 @@ static int gdsc_disable(struct generic_pm_domain *domain)
329356
return 0;
330357
}
331358

359+
static int gdsc_disable(struct generic_pm_domain *domain)
360+
{
361+
struct gdsc *sc = domain_to_gdsc(domain);
362+
int ret;
363+
364+
ret = _gdsc_disable(sc);
365+
366+
gdsc_pm_runtime_put(sc);
367+
368+
return ret;
369+
}
370+
332371
static int gdsc_init(struct gdsc *sc)
333372
{
334373
u32 mask, val;
@@ -443,6 +482,8 @@ int gdsc_register(struct gdsc_desc *desc,
443482
for (i = 0; i < num; i++) {
444483
if (!scs[i])
445484
continue;
485+
if (pm_runtime_enabled(dev))
486+
scs[i]->dev = dev;
446487
scs[i]->regmap = regmap;
447488
scs[i]->rcdev = rcdev;
448489
ret = gdsc_init(scs[i]);
@@ -457,6 +498,8 @@ int gdsc_register(struct gdsc_desc *desc,
457498
continue;
458499
if (scs[i]->parent)
459500
pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd);
501+
else if (!IS_ERR_OR_NULL(dev->pm_domain))
502+
pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
460503
}
461504

462505
return of_genpd_add_provider_onecell(dev->of_node, data);
@@ -475,6 +518,8 @@ void gdsc_unregister(struct gdsc_desc *desc)
475518
continue;
476519
if (scs[i]->parent)
477520
pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd);
521+
else if (!IS_ERR_OR_NULL(dev->pm_domain))
522+
pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
478523
}
479524
of_genpd_del_provider(dev->of_node);
480525
}

drivers/clk/qcom/gdsc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ struct reset_controller_dev;
2525
* @resets: ids of resets associated with this gdsc
2626
* @reset_count: number of @resets
2727
* @rcdev: reset controller
28+
* @dev: the device holding the GDSC, used for pm_runtime calls
2829
*/
2930
struct gdsc {
3031
struct generic_pm_domain pd;
@@ -58,6 +59,7 @@ struct gdsc {
5859

5960
const char *supply;
6061
struct regulator *rsupply;
62+
struct device *dev;
6163
};
6264

6365
struct gdsc_desc {

0 commit comments

Comments
 (0)