aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/devfreq/devfreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/devfreq/devfreq.c')
-rw-r--r--drivers/devfreq/devfreq.c90
1 files changed, 59 insertions, 31 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 0ae3de76833b..6b6991f0e873 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -29,6 +29,9 @@
29#include <linux/of.h> 29#include <linux/of.h>
30#include "governor.h" 30#include "governor.h"
31 31
32#define CREATE_TRACE_POINTS
33#include <trace/events/devfreq.h>
34
32static struct class *devfreq_class; 35static struct class *devfreq_class;
33 36
34/* 37/*
@@ -228,7 +231,7 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
228 * if is not found. This can happen when both drivers (the governor driver 231 * if is not found. This can happen when both drivers (the governor driver
229 * and the driver that call devfreq_add_device) are built as modules. 232 * and the driver that call devfreq_add_device) are built as modules.
230 * devfreq_list_lock should be held by the caller. Returns the matched 233 * devfreq_list_lock should be held by the caller. Returns the matched
231 * governor's pointer. 234 * governor's pointer or an error pointer.
232 */ 235 */
233static struct devfreq_governor *try_then_request_governor(const char *name) 236static struct devfreq_governor *try_then_request_governor(const char *name)
234{ 237{
@@ -254,7 +257,7 @@ static struct devfreq_governor *try_then_request_governor(const char *name)
254 /* Restore previous state before return */ 257 /* Restore previous state before return */
255 mutex_lock(&devfreq_list_lock); 258 mutex_lock(&devfreq_list_lock);
256 if (err) 259 if (err)
257 return NULL; 260 return ERR_PTR(err);
258 261
259 governor = find_devfreq_governor(name); 262 governor = find_devfreq_governor(name);
260 } 263 }
@@ -394,6 +397,8 @@ static void devfreq_monitor(struct work_struct *work)
394 queue_delayed_work(devfreq_wq, &devfreq->work, 397 queue_delayed_work(devfreq_wq, &devfreq->work,
395 msecs_to_jiffies(devfreq->profile->polling_ms)); 398 msecs_to_jiffies(devfreq->profile->polling_ms));
396 mutex_unlock(&devfreq->lock); 399 mutex_unlock(&devfreq->lock);
400
401 trace_devfreq_monitor(devfreq);
397} 402}
398 403
399/** 404/**
@@ -528,7 +533,7 @@ void devfreq_interval_update(struct devfreq *devfreq, unsigned int *delay)
528 mutex_lock(&devfreq->lock); 533 mutex_lock(&devfreq->lock);
529 if (!devfreq->stop_polling) 534 if (!devfreq->stop_polling)
530 queue_delayed_work(devfreq_wq, &devfreq->work, 535 queue_delayed_work(devfreq_wq, &devfreq->work,
531 msecs_to_jiffies(devfreq->profile->polling_ms)); 536 msecs_to_jiffies(devfreq->profile->polling_ms));
532 } 537 }
533out: 538out:
534 mutex_unlock(&devfreq->lock); 539 mutex_unlock(&devfreq->lock);
@@ -537,7 +542,7 @@ EXPORT_SYMBOL(devfreq_interval_update);
537 542
538/** 543/**
539 * devfreq_notifier_call() - Notify that the device frequency requirements 544 * devfreq_notifier_call() - Notify that the device frequency requirements
540 * has been changed out of devfreq framework. 545 * has been changed out of devfreq framework.
541 * @nb: the notifier_block (supposed to be devfreq->nb) 546 * @nb: the notifier_block (supposed to be devfreq->nb)
542 * @type: not used 547 * @type: not used
543 * @devp: not used 548 * @devp: not used
@@ -651,7 +656,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
651 mutex_unlock(&devfreq->lock); 656 mutex_unlock(&devfreq->lock);
652 err = set_freq_table(devfreq); 657 err = set_freq_table(devfreq);
653 if (err < 0) 658 if (err < 0)
654 goto err_out; 659 goto err_dev;
655 mutex_lock(&devfreq->lock); 660 mutex_lock(&devfreq->lock);
656 } 661 }
657 662
@@ -683,16 +688,27 @@ struct devfreq *devfreq_add_device(struct device *dev,
683 goto err_out; 688 goto err_out;
684 } 689 }
685 690
686 devfreq->trans_table = 691 devfreq->trans_table = devm_kzalloc(&devfreq->dev,
687 devm_kzalloc(&devfreq->dev, 692 array3_size(sizeof(unsigned int),
688 array3_size(sizeof(unsigned int), 693 devfreq->profile->max_state,
689 devfreq->profile->max_state, 694 devfreq->profile->max_state),
690 devfreq->profile->max_state), 695 GFP_KERNEL);
691 GFP_KERNEL); 696 if (!devfreq->trans_table) {
697 mutex_unlock(&devfreq->lock);
698 err = -ENOMEM;
699 goto err_devfreq;
700 }
701
692 devfreq->time_in_state = devm_kcalloc(&devfreq->dev, 702 devfreq->time_in_state = devm_kcalloc(&devfreq->dev,
693 devfreq->profile->max_state, 703 devfreq->profile->max_state,
694 sizeof(unsigned long), 704 sizeof(unsigned long),
695 GFP_KERNEL); 705 GFP_KERNEL);
706 if (!devfreq->time_in_state) {
707 mutex_unlock(&devfreq->lock);
708 err = -ENOMEM;
709 goto err_devfreq;
710 }
711
696 devfreq->last_stat_updated = jiffies; 712 devfreq->last_stat_updated = jiffies;
697 713
698 srcu_init_notifier_head(&devfreq->transition_notifier_list); 714 srcu_init_notifier_head(&devfreq->transition_notifier_list);
@@ -726,7 +742,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
726 742
727err_init: 743err_init:
728 mutex_unlock(&devfreq_list_lock); 744 mutex_unlock(&devfreq_list_lock);
729 745err_devfreq:
730 devfreq_remove_device(devfreq); 746 devfreq_remove_device(devfreq);
731 devfreq = NULL; 747 devfreq = NULL;
732err_dev: 748err_dev:
@@ -1113,7 +1129,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
1113 struct devfreq *df = to_devfreq(dev); 1129 struct devfreq *df = to_devfreq(dev);
1114 int ret; 1130 int ret;
1115 char str_governor[DEVFREQ_NAME_LEN + 1]; 1131 char str_governor[DEVFREQ_NAME_LEN + 1];
1116 struct devfreq_governor *governor; 1132 const struct devfreq_governor *governor, *prev_governor;
1117 1133
1118 ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor); 1134 ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor);
1119 if (ret != 1) 1135 if (ret != 1)
@@ -1142,12 +1158,24 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
1142 goto out; 1158 goto out;
1143 } 1159 }
1144 } 1160 }
1161 prev_governor = df->governor;
1145 df->governor = governor; 1162 df->governor = governor;
1146 strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN); 1163 strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN);
1147 ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL); 1164 ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
1148 if (ret) 1165 if (ret) {
1149 dev_warn(dev, "%s: Governor %s not started(%d)\n", 1166 dev_warn(dev, "%s: Governor %s not started(%d)\n",
1150 __func__, df->governor->name, ret); 1167 __func__, df->governor->name, ret);
1168 df->governor = prev_governor;
1169 strncpy(df->governor_name, prev_governor->name,
1170 DEVFREQ_NAME_LEN);
1171 ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
1172 if (ret) {
1173 dev_err(dev,
1174 "%s: reverting to Governor %s failed (%d)\n",
1175 __func__, df->governor_name, ret);
1176 df->governor = NULL;
1177 }
1178 }
1151out: 1179out:
1152 mutex_unlock(&devfreq_list_lock); 1180 mutex_unlock(&devfreq_list_lock);
1153 1181
@@ -1172,7 +1200,7 @@ static ssize_t available_governors_show(struct device *d,
1172 */ 1200 */
1173 if (df->governor->immutable) { 1201 if (df->governor->immutable) {
1174 count = scnprintf(&buf[count], DEVFREQ_NAME_LEN, 1202 count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
1175 "%s ", df->governor_name); 1203 "%s ", df->governor_name);
1176 /* 1204 /*
1177 * The devfreq device shows the registered governor except for 1205 * The devfreq device shows the registered governor except for
1178 * immutable governors such as passive governor . 1206 * immutable governors such as passive governor .
@@ -1485,8 +1513,8 @@ EXPORT_SYMBOL(devfreq_recommended_opp);
1485 1513
1486/** 1514/**
1487 * devfreq_register_opp_notifier() - Helper function to get devfreq notified 1515 * devfreq_register_opp_notifier() - Helper function to get devfreq notified
1488 * for any changes in the OPP availability 1516 * for any changes in the OPP availability
1489 * changes 1517 * changes
1490 * @dev: The devfreq user device. (parent of devfreq) 1518 * @dev: The devfreq user device. (parent of devfreq)
1491 * @devfreq: The devfreq object. 1519 * @devfreq: The devfreq object.
1492 */ 1520 */
@@ -1498,8 +1526,8 @@ EXPORT_SYMBOL(devfreq_register_opp_notifier);
1498 1526
1499/** 1527/**
1500 * devfreq_unregister_opp_notifier() - Helper function to stop getting devfreq 1528 * devfreq_unregister_opp_notifier() - Helper function to stop getting devfreq
1501 * notified for any changes in the OPP 1529 * notified for any changes in the OPP
1502 * availability changes anymore. 1530 * availability changes anymore.
1503 * @dev: The devfreq user device. (parent of devfreq) 1531 * @dev: The devfreq user device. (parent of devfreq)
1504 * @devfreq: The devfreq object. 1532 * @devfreq: The devfreq object.
1505 * 1533 *
@@ -1518,8 +1546,8 @@ static void devm_devfreq_opp_release(struct device *dev, void *res)
1518} 1546}
1519 1547
1520/** 1548/**
1521 * devm_ devfreq_register_opp_notifier() 1549 * devm_devfreq_register_opp_notifier() - Resource-managed
1522 * - Resource-managed devfreq_register_opp_notifier() 1550 * devfreq_register_opp_notifier()
1523 * @dev: The devfreq user device. (parent of devfreq) 1551 * @dev: The devfreq user device. (parent of devfreq)
1524 * @devfreq: The devfreq object. 1552 * @devfreq: The devfreq object.
1525 */ 1553 */
@@ -1547,8 +1575,8 @@ int devm_devfreq_register_opp_notifier(struct device *dev,
1547EXPORT_SYMBOL(devm_devfreq_register_opp_notifier); 1575EXPORT_SYMBOL(devm_devfreq_register_opp_notifier);
1548 1576
1549/** 1577/**
1550 * devm_devfreq_unregister_opp_notifier() 1578 * devm_devfreq_unregister_opp_notifier() - Resource-managed
1551 * - Resource-managed devfreq_unregister_opp_notifier() 1579 * devfreq_unregister_opp_notifier()
1552 * @dev: The devfreq user device. (parent of devfreq) 1580 * @dev: The devfreq user device. (parent of devfreq)
1553 * @devfreq: The devfreq object. 1581 * @devfreq: The devfreq object.
1554 */ 1582 */
@@ -1567,8 +1595,8 @@ EXPORT_SYMBOL(devm_devfreq_unregister_opp_notifier);
1567 * @list: DEVFREQ_TRANSITION_NOTIFIER. 1595 * @list: DEVFREQ_TRANSITION_NOTIFIER.
1568 */ 1596 */
1569int devfreq_register_notifier(struct devfreq *devfreq, 1597int devfreq_register_notifier(struct devfreq *devfreq,
1570 struct notifier_block *nb, 1598 struct notifier_block *nb,
1571 unsigned int list) 1599 unsigned int list)
1572{ 1600{
1573 int ret = 0; 1601 int ret = 0;
1574 1602
@@ -1674,9 +1702,9 @@ EXPORT_SYMBOL(devm_devfreq_register_notifier);
1674 * @list: DEVFREQ_TRANSITION_NOTIFIER. 1702 * @list: DEVFREQ_TRANSITION_NOTIFIER.
1675 */ 1703 */
1676void devm_devfreq_unregister_notifier(struct device *dev, 1704void devm_devfreq_unregister_notifier(struct device *dev,
1677 struct devfreq *devfreq, 1705 struct devfreq *devfreq,
1678 struct notifier_block *nb, 1706 struct notifier_block *nb,
1679 unsigned int list) 1707 unsigned int list)
1680{ 1708{
1681 WARN_ON(devres_release(dev, devm_devfreq_notifier_release, 1709 WARN_ON(devres_release(dev, devm_devfreq_notifier_release,
1682 devm_devfreq_dev_match, devfreq)); 1710 devm_devfreq_dev_match, devfreq));