soc: rockchip: power-domain: export rockchip_pm_register_notify_to_dmc
authorFinley Xiao <finley.xiao@rock-chips.com>
Tue, 2 May 2017 07:15:26 +0000 (15:15 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 4 May 2017 07:00:54 +0000 (15:00 +0800)
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 <finley.xiao@rock-chips.com>
drivers/soc/rockchip/pm_domains.c
include/soc/rockchip/rockchip_dmc.h [new file with mode: 0644]

index 70404d66ed34b9efbd35c1c1c508c7415c9c63d3..e72f3e0ad1dfc8efe032faf0f415647e4ba40b10 100644 (file)
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/devfreq.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/err.h>
@@ -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 (file)
index 0000000..f85073f
--- /dev/null
@@ -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 <linux/devfreq.h>
+
+int rockchip_pm_register_notify_to_dmc(struct devfreq *devfreq);
+
+#endif