From: Finley Xiao Date: Tue, 2 May 2017 07:15:26 +0000 (+0800) Subject: soc: rockchip: power-domain: export rockchip_pm_register_notify_to_dmc X-Git-Tag: release-20171130_firefly~4^2~671 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a670400e8bd6f49299e8c301fd841c1101f0c2e9;p=firefly-linux-kernel-4.4.55.git soc: rockchip: power-domain: export rockchip_pm_register_notify_to_dmc This function registers a notifier to dmc devfreq, it will lock the mutex of pmu when scaling frequency, so that pd driver and dmc driver will not assess register PMU_BUS_IDLE_REQ at the same time. Change-Id: I0ba96599d9050d11924d032146e6b4d415629614 Signed-off-by: Finley Xiao --- diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 70404d66ed34..e72f3e0ad1df 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -76,9 +77,13 @@ struct rockchip_pmu { const struct rockchip_pmu_info *info; struct mutex mutex; /* mutex lock for pmu */ struct genpd_onecell_data genpd_data; + struct devfreq *devfreq; + struct notifier_block dmc_nb; struct generic_pm_domain *domains[]; }; +static struct rockchip_pmu *dmc_pmu; + #define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd) #define DOMAIN(pwr, status, req, idle, ack, wakeup) \ @@ -626,6 +631,30 @@ err_out: return error; } +static int dmc_notify(struct notifier_block *nb, unsigned long event, + void *data) +{ + if (event == DEVFREQ_PRECHANGE) + mutex_lock(&dmc_pmu->mutex); + else if (event == DEVFREQ_POSTCHANGE) + mutex_unlock(&dmc_pmu->mutex); + + return NOTIFY_OK; +} + +int rockchip_pm_register_notify_to_dmc(struct devfreq *devfreq) +{ + if (!dmc_pmu) + return -ENOMEM; + + dmc_pmu->devfreq = devfreq; + dmc_pmu->dmc_nb.notifier_call = dmc_notify; + devfreq_register_notifier(dmc_pmu->devfreq, &dmc_pmu->dmc_nb, + DEVFREQ_TRANSITION_NOTIFIER); + return 0; +} +EXPORT_SYMBOL(rockchip_pm_register_notify_to_dmc); + static int rockchip_pm_domain_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -715,6 +744,8 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev) of_genpd_add_provider_onecell(np, &pmu->genpd_data); + dmc_pmu = pmu; + return 0; err_out: diff --git a/include/soc/rockchip/rockchip_dmc.h b/include/soc/rockchip/rockchip_dmc.h new file mode 100644 index 000000000000..f85073f1f59d --- /dev/null +++ b/include/soc/rockchip/rockchip_dmc.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#ifndef __SOC_ROCKCHIP_DMC_H +#define __SOC_ROCKCHIP_DMC_H + +#include + +int rockchip_pm_register_notify_to_dmc(struct devfreq *devfreq); + +#endif