aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorDaniel Lezcano <daniel.lezcano@linaro.org>2015-09-01 14:37:49 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-09-25 20:43:32 -0400
commitcea3ad93d9a5e054d916f1ad71da02cb306e4828 (patch)
treea916ab9a7e4c7ddcc51b1a77d8699044de55b05d /drivers/base
parentc6f7b48e7e21989f4cfc996837d55c595d5dbf87 (diff)
PM / Domains: Remove cpuidle attach
The power domains code allows to tie a cpuidle state with a power domain. Preventing the cpuidle framework to enter a specific idle state by disabling from the power domain framework is a good idea. Unfortunately, the current implementation has some gaps with a SMP system and a complex cpuidle implementation. Enabling a power domain wakes up all the cpus even if a cpu does not belong to the power domain. There is some work to do a logical representation with the power domains of the hardware dependencies (eg. a cpu belongs to a power domains, these power domains belong to a higher power domain for a cluster, etc ...). A new code relying on the genpd hierarchy to disable the idle states would make more sense. As the unique user of this code has been removed, let's wipe out this code to prevent new user and to have a clean place to put a new implementation. Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Acked-by: Kevin Hilman <khilman@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/domain.c135
1 files changed, 0 insertions, 135 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index a46427e72034..a544887d03c7 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -122,19 +122,6 @@ static void genpd_sd_counter_inc(struct generic_pm_domain *genpd)
122 smp_mb__after_atomic(); 122 smp_mb__after_atomic();
123} 123}
124 124
125static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
126{
127 s64 usecs64;
128
129 if (!genpd->cpuidle_data)
130 return;
131
132 usecs64 = genpd->power_on_latency_ns;
133 do_div(usecs64, NSEC_PER_USEC);
134 usecs64 += genpd->cpuidle_data->saved_exit_latency;
135 genpd->cpuidle_data->idle_state->exit_latency = usecs64;
136}
137
138static int genpd_power_on(struct generic_pm_domain *genpd, bool timed) 125static int genpd_power_on(struct generic_pm_domain *genpd, bool timed)
139{ 126{
140 ktime_t time_start; 127 ktime_t time_start;
@@ -158,7 +145,6 @@ static int genpd_power_on(struct generic_pm_domain *genpd, bool timed)
158 145
159 genpd->power_on_latency_ns = elapsed_ns; 146 genpd->power_on_latency_ns = elapsed_ns;
160 genpd->max_off_time_changed = true; 147 genpd->max_off_time_changed = true;
161 genpd_recalc_cpu_exit_latency(genpd);
162 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", 148 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
163 genpd->name, "on", elapsed_ns); 149 genpd->name, "on", elapsed_ns);
164 150
@@ -222,13 +208,6 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
222 || (genpd->prepared_count > 0 && genpd->suspend_power_off)) 208 || (genpd->prepared_count > 0 && genpd->suspend_power_off))
223 return 0; 209 return 0;
224 210
225 if (genpd->cpuidle_data) {
226 cpuidle_pause_and_lock();
227 genpd->cpuidle_data->idle_state->disabled = true;
228 cpuidle_resume_and_unlock();
229 goto out;
230 }
231
232 /* 211 /*
233 * The list is guaranteed not to change while the loop below is being 212 * The list is guaranteed not to change while the loop below is being
234 * executed, unless one of the masters' .power_on() callbacks fiddles 213 * executed, unless one of the masters' .power_on() callbacks fiddles
@@ -381,21 +360,6 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
381 return -EAGAIN; 360 return -EAGAIN;
382 } 361 }
383 362
384 if (genpd->cpuidle_data) {
385 /*
386 * If cpuidle_data is set, cpuidle should turn the domain off
387 * when the CPU in it is idle. In that case we don't decrement
388 * the subdomain counts of the master domains, so that power is
389 * not removed from the current domain prematurely as a result
390 * of cutting off the masters' power.
391 */
392 genpd->status = GPD_STATE_POWER_OFF;
393 cpuidle_pause_and_lock();
394 genpd->cpuidle_data->idle_state->disabled = false;
395 cpuidle_resume_and_unlock();
396 return 0;
397 }
398
399 if (genpd->power_off) { 363 if (genpd->power_off) {
400 int ret; 364 int ret;
401 365
@@ -1433,105 +1397,6 @@ out:
1433 return ret; 1397 return ret;
1434} 1398}
1435 1399
1436/**
1437 * pm_genpd_attach_cpuidle - Connect the given PM domain with cpuidle.
1438 * @genpd: PM domain to be connected with cpuidle.
1439 * @state: cpuidle state this domain can disable/enable.
1440 *
1441 * Make a PM domain behave as though it contained a CPU core, that is, instead
1442 * of calling its power down routine it will enable the given cpuidle state so
1443 * that the cpuidle subsystem can power it down (if possible and desirable).
1444 */
1445int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
1446{
1447 struct cpuidle_driver *cpuidle_drv;
1448 struct gpd_cpuidle_data *cpuidle_data;
1449 struct cpuidle_state *idle_state;
1450 int ret = 0;
1451
1452 if (IS_ERR_OR_NULL(genpd) || state < 0)
1453 return -EINVAL;
1454
1455 mutex_lock(&genpd->lock);
1456
1457 if (genpd->cpuidle_data) {
1458 ret = -EEXIST;
1459 goto out;
1460 }
1461 cpuidle_data = kzalloc(sizeof(*cpuidle_data), GFP_KERNEL);
1462 if (!cpuidle_data) {
1463 ret = -ENOMEM;
1464 goto out;
1465 }
1466 cpuidle_drv = cpuidle_driver_ref();
1467 if (!cpuidle_drv) {
1468 ret = -ENODEV;
1469 goto err_drv;
1470 }
1471 if (cpuidle_drv->state_count <= state) {
1472 ret = -EINVAL;
1473 goto err;
1474 }
1475 idle_state = &cpuidle_drv->states[state];
1476 if (!idle_state->disabled) {
1477 ret = -EAGAIN;
1478 goto err;
1479 }
1480 cpuidle_data->idle_state = idle_state;
1481 cpuidle_data->saved_exit_latency = idle_state->exit_latency;
1482 genpd->cpuidle_data = cpuidle_data;
1483 genpd_recalc_cpu_exit_latency(genpd);
1484
1485 out:
1486 mutex_unlock(&genpd->lock);
1487 return ret;
1488
1489 err:
1490 cpuidle_driver_unref();
1491
1492 err_drv:
1493 kfree(cpuidle_data);
1494 goto out;
1495}
1496
1497/**
1498 * pm_genpd_detach_cpuidle - Remove the cpuidle connection from a PM domain.
1499 * @genpd: PM domain to remove the cpuidle connection from.
1500 *
1501 * Remove the cpuidle connection set up by pm_genpd_attach_cpuidle() from the
1502 * given PM domain.
1503 */
1504int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
1505{
1506 struct gpd_cpuidle_data *cpuidle_data;
1507 struct cpuidle_state *idle_state;
1508 int ret = 0;
1509
1510 if (IS_ERR_OR_NULL(genpd))
1511 return -EINVAL;
1512
1513 mutex_lock(&genpd->lock);
1514
1515 cpuidle_data = genpd->cpuidle_data;
1516 if (!cpuidle_data) {
1517 ret = -ENODEV;
1518 goto out;
1519 }
1520 idle_state = cpuidle_data->idle_state;
1521 if (!idle_state->disabled) {
1522 ret = -EAGAIN;
1523 goto out;
1524 }
1525 idle_state->exit_latency = cpuidle_data->saved_exit_latency;
1526 cpuidle_driver_unref();
1527 genpd->cpuidle_data = NULL;
1528 kfree(cpuidle_data);
1529
1530 out:
1531 mutex_unlock(&genpd->lock);
1532 return ret;
1533}
1534
1535/* Default device callbacks for generic PM domains. */ 1400/* Default device callbacks for generic PM domains. */
1536 1401
1537/** 1402/**