Merge branches 'pm-domains', 'pm-avs' and 'powercap'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 3 Jul 2017 12:22:34 +0000 (14:22 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 3 Jul 2017 12:22:34 +0000 (14:22 +0200)
* pm-domains:
  PM / Domains: Fix missing default_power_down_ok comment
  PM / Domains: Fix unsafe iteration over modified list of domains
  PM / Domains: Fix unsafe iteration over modified list of domain providers
  PM / Domains: Fix unsafe iteration over modified list of device links
  PM / Domains: Handle safely genpd_syscore_switch() call on non-genpd device
  PM / Domains: Call driver's noirq callbacks
  PM / Domains: Constify genpd pointer
  PM / Domains: pdd->dev can't be NULL in genpd_dev_pm_qos_notifier()

* pm-avs:
  PM / AVS: rockchip-io: add io selectors and supplies for rk3228

* powercap:
  powercap/RAPL: prevent overridding bits outside of the mask

Documentation/devicetree/bindings/power/rockchip-io-domain.txt
drivers/base/power/domain.c
drivers/base/power/domain_governor.c
drivers/power/avs/rockchip-io-domain.c
drivers/powercap/intel_rapl.c

index d3a5a93a65cd255ff8f5bc3cafcc2fd967d99147..43c21fb04564c1c19d10043d2425dfe8654b69ba 100644 (file)
@@ -32,6 +32,7 @@ SoC is on the same page.
 Required properties:
 - compatible: should be one of:
   - "rockchip,rk3188-io-voltage-domain" for rk3188
+  - "rockchip,rk3228-io-voltage-domain" for rk3228
   - "rockchip,rk3288-io-voltage-domain" for rk3288
   - "rockchip,rk3328-io-voltage-domain" for rk3328
   - "rockchip,rk3368-io-voltage-domain" for rk3368
@@ -59,6 +60,12 @@ Possible supplies for rk3188:
 - vccio1-supply: The supply connected to VCCIO1.
                  Sometimes also labeled VCCIO1 and VCCIO2.
 
+Possible supplies for rk3228:
+- vccio1-supply: The supply connected to VCCIO1.
+- vccio2-supply: The supply connected to VCCIO2.
+- vccio3-supply: The supply connected to VCCIO3.
+- vccio4-supply: The supply connected to VCCIO4.
+
 Possible supplies for rk3288:
 - audio-supply:  The supply connected to APIO4_VDD.
 - bb-supply:     The supply connected to APIO5_VDD.
index da49a8383dc30b074d28463e3b2771cd2ebd8adb..b8e4b966c74dc393b473da4f0074b802b8add5f8 100644 (file)
@@ -126,7 +126,7 @@ static const struct genpd_lock_ops genpd_spin_ops = {
 #define genpd_is_always_on(genpd)      (genpd->flags & GENPD_FLAG_ALWAYS_ON)
 
 static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev,
-               struct generic_pm_domain *genpd)
+               const struct generic_pm_domain *genpd)
 {
        bool ret;
 
@@ -181,12 +181,14 @@ static struct generic_pm_domain *dev_to_genpd(struct device *dev)
        return pd_to_genpd(dev->pm_domain);
 }
 
-static int genpd_stop_dev(struct generic_pm_domain *genpd, struct device *dev)
+static int genpd_stop_dev(const struct generic_pm_domain *genpd,
+                         struct device *dev)
 {
        return GENPD_DEV_CALLBACK(genpd, int, stop, dev);
 }
 
-static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev)
+static int genpd_start_dev(const struct generic_pm_domain *genpd,
+                          struct device *dev)
 {
        return GENPD_DEV_CALLBACK(genpd, int, start, dev);
 }
@@ -443,7 +445,7 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
 
                pdd = dev->power.subsys_data ?
                                dev->power.subsys_data->domain_data : NULL;
-               if (pdd && pdd->dev) {
+               if (pdd) {
                        to_gpd_data(pdd)->td.constraint_changed = true;
                        genpd = dev_to_genpd(dev);
                } else {
@@ -738,7 +740,7 @@ static bool pm_genpd_present(const struct generic_pm_domain *genpd)
 
 #ifdef CONFIG_PM_SLEEP
 
-static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd,
+static bool genpd_dev_active_wakeup(const struct generic_pm_domain *genpd,
                                    struct device *dev)
 {
        return GENPD_DEV_CALLBACK(genpd, bool, active_wakeup, dev);
@@ -840,7 +842,8 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock,
  * signal remote wakeup from the system's working state as needed by runtime PM.
  * Return 'true' in either of the above cases.
  */
-static bool resume_needed(struct device *dev, struct generic_pm_domain *genpd)
+static bool resume_needed(struct device *dev,
+                         const struct generic_pm_domain *genpd)
 {
        bool active_wakeup;
 
@@ -899,19 +902,19 @@ static int pm_genpd_prepare(struct device *dev)
 }
 
 /**
- * pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
+ * genpd_finish_suspend - Completion of suspend or hibernation of device in an
+ *   I/O pm domain.
  * @dev: Device to suspend.
+ * @poweroff: Specifies if this is a poweroff_noirq or suspend_noirq callback.
  *
  * Stop the device and remove power from the domain if all devices in it have
  * been stopped.
  */
-static int pm_genpd_suspend_noirq(struct device *dev)
+static int genpd_finish_suspend(struct device *dev, bool poweroff)
 {
        struct generic_pm_domain *genpd;
        int ret;
 
-       dev_dbg(dev, "%s()\n", __func__);
-
        genpd = dev_to_genpd(dev);
        if (IS_ERR(genpd))
                return -EINVAL;
@@ -919,6 +922,13 @@ static int pm_genpd_suspend_noirq(struct device *dev)
        if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))
                return 0;
 
+       if (poweroff)
+               ret = pm_generic_poweroff_noirq(dev);
+       else
+               ret = pm_generic_suspend_noirq(dev);
+       if (ret)
+               return ret;
+
        if (genpd->dev_ops.stop && genpd->dev_ops.start) {
                ret = pm_runtime_force_suspend(dev);
                if (ret)
@@ -933,6 +943,20 @@ static int pm_genpd_suspend_noirq(struct device *dev)
        return 0;
 }
 
+/**
+ * pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
+ * @dev: Device to suspend.
+ *
+ * Stop the device and remove power from the domain if all devices in it have
+ * been stopped.
+ */
+static int pm_genpd_suspend_noirq(struct device *dev)
+{
+       dev_dbg(dev, "%s()\n", __func__);
+
+       return genpd_finish_suspend(dev, false);
+}
+
 /**
  * pm_genpd_resume_noirq - Start of resume of device in an I/O PM domain.
  * @dev: Device to resume.
@@ -961,6 +985,10 @@ static int pm_genpd_resume_noirq(struct device *dev)
        if (genpd->dev_ops.stop && genpd->dev_ops.start)
                ret = pm_runtime_force_resume(dev);
 
+       ret = pm_generic_resume_noirq(dev);
+       if (ret)
+               return ret;
+
        return ret;
 }
 
@@ -975,7 +1003,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
  */
 static int pm_genpd_freeze_noirq(struct device *dev)
 {
-       struct generic_pm_domain *genpd;
+       const struct generic_pm_domain *genpd;
        int ret = 0;
 
        dev_dbg(dev, "%s()\n", __func__);
@@ -984,6 +1012,10 @@ static int pm_genpd_freeze_noirq(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
+       ret = pm_generic_freeze_noirq(dev);
+       if (ret)
+               return ret;
+
        if (genpd->dev_ops.stop && genpd->dev_ops.start)
                ret = pm_runtime_force_suspend(dev);
 
@@ -999,7 +1031,7 @@ static int pm_genpd_freeze_noirq(struct device *dev)
  */
 static int pm_genpd_thaw_noirq(struct device *dev)
 {
-       struct generic_pm_domain *genpd;
+       const struct generic_pm_domain *genpd;
        int ret = 0;
 
        dev_dbg(dev, "%s()\n", __func__);
@@ -1008,10 +1040,28 @@ static int pm_genpd_thaw_noirq(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       if (genpd->dev_ops.stop && genpd->dev_ops.start)
+       if (genpd->dev_ops.stop && genpd->dev_ops.start) {
                ret = pm_runtime_force_resume(dev);
+               if (ret)
+                       return ret;
+       }
 
-       return ret;
+       return pm_generic_thaw_noirq(dev);
+}
+
+/**
+ * pm_genpd_poweroff_noirq - Completion of hibernation of device in an
+ *   I/O PM domain.
+ * @dev: Device to poweroff.
+ *
+ * Stop the device and remove power from the domain if all devices in it have
+ * been stopped.
+ */
+static int pm_genpd_poweroff_noirq(struct device *dev)
+{
+       dev_dbg(dev, "%s()\n", __func__);
+
+       return genpd_finish_suspend(dev, true);
 }
 
 /**
@@ -1048,10 +1098,13 @@ static int pm_genpd_restore_noirq(struct device *dev)
        genpd_sync_power_on(genpd, true, 0);
        genpd_unlock(genpd);
 
-       if (genpd->dev_ops.stop && genpd->dev_ops.start)
+       if (genpd->dev_ops.stop && genpd->dev_ops.start) {
                ret = pm_runtime_force_resume(dev);
+               if (ret)
+                       return ret;
+       }
 
-       return ret;
+       return pm_generic_restore_noirq(dev);
 }
 
 /**
@@ -1095,8 +1148,8 @@ static void genpd_syscore_switch(struct device *dev, bool suspend)
 {
        struct generic_pm_domain *genpd;
 
-       genpd = dev_to_genpd(dev);
-       if (!pm_genpd_present(genpd))
+       genpd = genpd_lookup_dev(dev);
+       if (!genpd)
                return;
 
        if (suspend) {
@@ -1393,7 +1446,7 @@ EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain);
 int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
                              struct generic_pm_domain *subdomain)
 {
-       struct gpd_link *link;
+       struct gpd_link *l, *link;
        int ret = -EINVAL;
 
        if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
@@ -1409,7 +1462,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
                goto out;
        }
 
-       list_for_each_entry(link, &genpd->master_links, master_node) {
+       list_for_each_entry_safe(link, l, &genpd->master_links, master_node) {
                if (link->slave != subdomain)
                        continue;
 
@@ -1493,7 +1546,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
        genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq;
        genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq;
        genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq;
-       genpd->domain.ops.poweroff_noirq = pm_genpd_suspend_noirq;
+       genpd->domain.ops.poweroff_noirq = pm_genpd_poweroff_noirq;
        genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq;
        genpd->domain.ops.complete = pm_genpd_complete;
 
@@ -1780,12 +1833,12 @@ EXPORT_SYMBOL_GPL(of_genpd_add_provider_onecell);
  */
 void of_genpd_del_provider(struct device_node *np)
 {
-       struct of_genpd_provider *cp;
+       struct of_genpd_provider *cp, *tmp;
        struct generic_pm_domain *gpd;
 
        mutex_lock(&gpd_list_lock);
        mutex_lock(&of_genpd_mutex);
-       list_for_each_entry(cp, &of_genpd_providers, link) {
+       list_for_each_entry_safe(cp, tmp, &of_genpd_providers, link) {
                if (cp->node == np) {
                        /*
                         * For each PM domain associated with the
@@ -1925,14 +1978,14 @@ EXPORT_SYMBOL_GPL(of_genpd_add_subdomain);
  */
 struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
 {
-       struct generic_pm_domain *gpd, *genpd = ERR_PTR(-ENOENT);
+       struct generic_pm_domain *gpd, *tmp, *genpd = ERR_PTR(-ENOENT);
        int ret;
 
        if (IS_ERR_OR_NULL(np))
                return ERR_PTR(-EINVAL);
 
        mutex_lock(&gpd_list_lock);
-       list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
+       list_for_each_entry_safe(gpd, tmp, &gpd_list, gpd_list_node) {
                if (gpd->provider == &np->fwnode) {
                        ret = genpd_remove(gpd);
                        genpd = ret ? ERR_PTR(ret) : gpd;
index 2e0fce711135cd68d5c6ee72e23b62eaa1825b69..281f949c5ffeb22828e0363c6c4c302c7635eb92 100644 (file)
@@ -92,12 +92,6 @@ static bool default_suspend_ok(struct device *dev)
        return td->cached_suspend_ok;
 }
 
-/**
- * default_power_down_ok - Default generic PM domain power off governor routine.
- * @pd: PM domain to check.
- *
- * This routine must be executed under the PM domain's lock.
- */
 static bool __default_power_down_ok(struct dev_pm_domain *pd,
                                     unsigned int state)
 {
@@ -187,6 +181,12 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd,
        return true;
 }
 
+/**
+ * default_power_down_ok - Default generic PM domain power off governor routine.
+ * @pd: PM domain to check.
+ *
+ * This routine must be executed under the PM domain's lock.
+ */
 static bool default_power_down_ok(struct dev_pm_domain *pd)
 {
        struct generic_pm_domain *genpd = pd_to_genpd(pd);
index 85812521b6baddf00f47bb2b1a9cfa095ff661a4..031a34372191a832a39858487d3e21c22d2fad61 100644 (file)
@@ -253,6 +253,16 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3188 = {
        },
 };
 
+static const struct rockchip_iodomain_soc_data soc_data_rk3228 = {
+       .grf_offset = 0x418,
+       .supply_names = {
+               "vccio1",
+               "vccio2",
+               "vccio3",
+               "vccio4",
+       },
+};
+
 static const struct rockchip_iodomain_soc_data soc_data_rk3288 = {
        .grf_offset = 0x380,
        .supply_names = {
@@ -344,6 +354,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
                .compatible = "rockchip,rk3188-io-voltage-domain",
                .data = (void *)&soc_data_rk3188
        },
+       {
+               .compatible = "rockchip,rk3228-io-voltage-domain",
+               .data = (void *)&soc_data_rk3228
+       },
        {
                .compatible = "rockchip,rk3288-io-voltage-domain",
                .data = (void *)&soc_data_rk3288
index 9ddad0815ba909a7c77de8f93db06e7bc712d246..d1694f1def7278d17249bbbc23e0a64b3704ba5d 100644 (file)
@@ -874,7 +874,9 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
 
        cpu = rd->rp->lead_cpu;
        bits = rapl_unit_xlate(rd, rp->unit, value, 1);
-       bits |= bits << rp->shift;
+       bits <<= rp->shift;
+       bits &= rp->mask;
+
        memset(&ma, 0, sizeof(ma));
 
        ma.msr_no = rd->msrs[rp->id];