浏览代码

Merge branch 'pm-devfreq'

* pm-devfreq:
  MAINTAINERS: Add devfreq-event entry
  MAINTAINERS: Add missing git repository and directory for devfreq
  PM / devfreq: Do not show statistics if it's not ready.
  PM / devfreq: Modify the indentation of trans_stat sysfs for readability
  PM / devfreq: Set the freq_table of devfreq device
  PM / devfreq: Add show_one macro to delete the duplicate code
  PM / devfreq: event: Fix the error and warning from script/checkpatch.pl
  PM / devfreq: event: Remove the error log of devfreq_event_get_edev_by_phandle()
Rafael J. Wysocki 9 年之前
父节点
当前提交
fa8bb45187
共有 4 个文件被更改,包括 81 次插入28 次删除
  1. 13 0
      MAINTAINERS
  2. 5 11
      drivers/devfreq/devfreq-event.c
  3. 62 16
      drivers/devfreq/devfreq.c
  4. 1 1
      include/linux/devfreq.h

+ 13 - 0
MAINTAINERS

@@ -3421,8 +3421,21 @@ DEVICE FREQUENCY (DEVFREQ)
 M:	MyungJoo Ham <myungjoo.ham@samsung.com>
 M:	MyungJoo Ham <myungjoo.ham@samsung.com>
 M:	Kyungmin Park <kyungmin.park@samsung.com>
 M:	Kyungmin Park <kyungmin.park@samsung.com>
 L:	linux-pm@vger.kernel.org
 L:	linux-pm@vger.kernel.org
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
 S:	Maintained
 S:	Maintained
 F:	drivers/devfreq/
 F:	drivers/devfreq/
+F:	include/linux/devfreq.h
+F:	Documentation/devicetree/bindings/devfreq/
+
+DEVICE FREQUENCY EVENT (DEVFREQ-EVENT)
+M:	Chanwoo Choi <cw00.choi@samsung.com>
+L:	linux-pm@vger.kernel.org
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
+S:	Supported
+F:	drivers/devfreq/event/
+F:	drivers/devfreq/devfreq-event.c
+F:	include/linux/devfreq-event.h
+F:	Documentation/devicetree/bindings/devfreq/event/
 
 
 DEVICE NUMBER REGISTRY
 DEVICE NUMBER REGISTRY
 M:	Torben Mathiasen <device@lanana.org>
 M:	Torben Mathiasen <device@lanana.org>

+ 5 - 11
drivers/devfreq/devfreq-event.c

@@ -226,17 +226,12 @@ struct devfreq_event_dev *devfreq_event_get_edev_by_phandle(struct device *dev,
 	struct device_node *node;
 	struct device_node *node;
 	struct devfreq_event_dev *edev;
 	struct devfreq_event_dev *edev;
 
 
-	if (!dev->of_node) {
-		dev_err(dev, "device does not have a device node entry\n");
+	if (!dev->of_node)
 		return ERR_PTR(-EINVAL);
 		return ERR_PTR(-EINVAL);
-	}
 
 
 	node = of_parse_phandle(dev->of_node, "devfreq-events", index);
 	node = of_parse_phandle(dev->of_node, "devfreq-events", index);
-	if (!node) {
-		dev_err(dev, "failed to get phandle in %s node\n",
-			dev->of_node->full_name);
+	if (!node)
 		return ERR_PTR(-ENODEV);
 		return ERR_PTR(-ENODEV);
-	}
 
 
 	mutex_lock(&devfreq_event_list_lock);
 	mutex_lock(&devfreq_event_list_lock);
 	list_for_each_entry(edev, &devfreq_event_list, node) {
 	list_for_each_entry(edev, &devfreq_event_list, node) {
@@ -248,8 +243,6 @@ out:
 	mutex_unlock(&devfreq_event_list_lock);
 	mutex_unlock(&devfreq_event_list_lock);
 
 
 	if (!edev) {
 	if (!edev) {
-		dev_err(dev, "unable to get devfreq-event device : %s\n",
-			node->name);
 		of_node_put(node);
 		of_node_put(node);
 		return ERR_PTR(-ENODEV);
 		return ERR_PTR(-ENODEV);
 	}
 	}
@@ -277,7 +270,7 @@ int devfreq_event_get_edev_count(struct device *dev)
 
 
 	count = of_property_count_elems_of_size(dev->of_node, "devfreq-events",
 	count = of_property_count_elems_of_size(dev->of_node, "devfreq-events",
 						sizeof(u32));
 						sizeof(u32));
-	if (count < 0 ) {
+	if (count < 0) {
 		dev_err(dev,
 		dev_err(dev,
 			"failed to get the count of devfreq-event in %s node\n",
 			"failed to get the count of devfreq-event in %s node\n",
 			dev->of_node->full_name);
 			dev->of_node->full_name);
@@ -402,7 +395,8 @@ struct devfreq_event_dev *devm_devfreq_event_add_edev(struct device *dev,
 {
 {
 	struct devfreq_event_dev **ptr, *edev;
 	struct devfreq_event_dev **ptr, *edev;
 
 
-	ptr = devres_alloc(devm_devfreq_event_release, sizeof(*ptr), GFP_KERNEL);
+	ptr = devres_alloc(devm_devfreq_event_release, sizeof(*ptr),
+				GFP_KERNEL);
 	if (!ptr)
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 		return ERR_PTR(-ENOMEM);
 
 

+ 62 - 16
drivers/devfreq/devfreq.c

@@ -84,6 +84,46 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq)
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
+/**
+ * devfreq_set_freq_table() - Initialize freq_table for the frequency
+ * @devfreq:	the devfreq instance
+ */
+static void devfreq_set_freq_table(struct devfreq *devfreq)
+{
+	struct devfreq_dev_profile *profile = devfreq->profile;
+	struct dev_pm_opp *opp;
+	unsigned long freq;
+	int i, count;
+
+	/* Initialize the freq_table from OPP table */
+	count = dev_pm_opp_get_opp_count(devfreq->dev.parent);
+	if (count <= 0)
+		return;
+
+	profile->max_state = count;
+	profile->freq_table = devm_kcalloc(devfreq->dev.parent,
+					profile->max_state,
+					sizeof(*profile->freq_table),
+					GFP_KERNEL);
+	if (!profile->freq_table) {
+		profile->max_state = 0;
+		return;
+	}
+
+	rcu_read_lock();
+	for (i = 0, freq = 0; i < profile->max_state; i++, freq++) {
+		opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq);
+		if (IS_ERR(opp)) {
+			devm_kfree(devfreq->dev.parent, profile->freq_table);
+			profile->max_state = 0;
+			rcu_read_unlock();
+			return;
+		}
+		profile->freq_table[i] = freq;
+	}
+	rcu_read_unlock();
+}
+
 /**
 /**
  * devfreq_update_status() - Update statistics of devfreq behavior
  * devfreq_update_status() - Update statistics of devfreq behavior
  * @devfreq:	the devfreq instance
  * @devfreq:	the devfreq instance
@@ -478,6 +518,12 @@ struct devfreq *devfreq_add_device(struct device *dev,
 	devfreq->data = data;
 	devfreq->data = data;
 	devfreq->nb.notifier_call = devfreq_notifier_call;
 	devfreq->nb.notifier_call = devfreq_notifier_call;
 
 
+	if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
+		mutex_unlock(&devfreq->lock);
+		devfreq_set_freq_table(devfreq);
+		mutex_lock(&devfreq->lock);
+	}
+
 	devfreq->trans_table =	devm_kzalloc(dev, sizeof(unsigned int) *
 	devfreq->trans_table =	devm_kzalloc(dev, sizeof(unsigned int) *
 						devfreq->profile->max_state *
 						devfreq->profile->max_state *
 						devfreq->profile->max_state,
 						devfreq->profile->max_state,
@@ -921,12 +967,6 @@ unlock:
 	return ret;
 	return ret;
 }
 }
 
 
-static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
-			     char *buf)
-{
-	return sprintf(buf, "%lu\n", to_devfreq(dev)->min_freq);
-}
-
 static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
 static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
 			      const char *buf, size_t count)
 			      const char *buf, size_t count)
 {
 {
@@ -953,13 +993,17 @@ unlock:
 	mutex_unlock(&df->lock);
 	mutex_unlock(&df->lock);
 	return ret;
 	return ret;
 }
 }
-static DEVICE_ATTR_RW(min_freq);
 
 
-static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
-			     char *buf)
-{
-	return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq);
+#define show_one(name)						\
+static ssize_t name##_show					\
+(struct device *dev, struct device_attribute *attr, char *buf)	\
+{								\
+	return sprintf(buf, "%lu\n", to_devfreq(dev)->name);	\
 }
 }
+show_one(min_freq);
+show_one(max_freq);
+
+static DEVICE_ATTR_RW(min_freq);
 static DEVICE_ATTR_RW(max_freq);
 static DEVICE_ATTR_RW(max_freq);
 
 
 static ssize_t available_frequencies_show(struct device *d,
 static ssize_t available_frequencies_show(struct device *d,
@@ -1005,11 +1049,13 @@ static ssize_t trans_stat_show(struct device *dev,
 	if (!devfreq->stop_polling &&
 	if (!devfreq->stop_polling &&
 			devfreq_update_status(devfreq, devfreq->previous_freq))
 			devfreq_update_status(devfreq, devfreq->previous_freq))
 		return 0;
 		return 0;
+	if (max_state == 0)
+		return sprintf(buf, "Not Supported.\n");
 
 
-	len = sprintf(buf, "   From  :   To\n");
-	len += sprintf(buf + len, "         :");
+	len = sprintf(buf, "     From  :   To\n");
+	len += sprintf(buf + len, "           :");
 	for (i = 0; i < max_state; i++)
 	for (i = 0; i < max_state; i++)
-		len += sprintf(buf + len, "%8u",
+		len += sprintf(buf + len, "%10lu",
 				devfreq->profile->freq_table[i]);
 				devfreq->profile->freq_table[i]);
 
 
 	len += sprintf(buf + len, "   time(ms)\n");
 	len += sprintf(buf + len, "   time(ms)\n");
@@ -1021,10 +1067,10 @@ static ssize_t trans_stat_show(struct device *dev,
 		} else {
 		} else {
 			len += sprintf(buf + len, " ");
 			len += sprintf(buf + len, " ");
 		}
 		}
-		len += sprintf(buf + len, "%8u:",
+		len += sprintf(buf + len, "%10lu:",
 				devfreq->profile->freq_table[i]);
 				devfreq->profile->freq_table[i]);
 		for (j = 0; j < max_state; j++)
 		for (j = 0; j < max_state; j++)
-			len += sprintf(buf + len, "%8u",
+			len += sprintf(buf + len, "%10u",
 				devfreq->trans_table[(i * max_state) + j]);
 				devfreq->trans_table[(i * max_state) + j]);
 		len += sprintf(buf + len, "%10u\n",
 		len += sprintf(buf + len, "%10u\n",
 			jiffies_to_msecs(devfreq->time_in_state[i]));
 			jiffies_to_msecs(devfreq->time_in_state[i]));

+ 1 - 1
include/linux/devfreq.h

@@ -89,7 +89,7 @@ struct devfreq_dev_profile {
 	int (*get_cur_freq)(struct device *dev, unsigned long *freq);
 	int (*get_cur_freq)(struct device *dev, unsigned long *freq);
 	void (*exit)(struct device *dev);
 	void (*exit)(struct device *dev);
 
 
-	unsigned int *freq_table;
+	unsigned long *freq_table;
 	unsigned int max_state;
 	unsigned int max_state;
 };
 };