forked from mirrors/linux
		
	PM / devfreq: Fix available_governor sysfs
The devfreq using passive governor is not able to change the governor.
So, the user can not change the governor through 'available_governor' sysfs
entry. Also, the devfreq which don't use the passive governor is not able to
change to 'passive' governor on the fly.
Fixes: 996133119f ("PM / devfreq: Add new passive governor")
Cc: stable@vger.kernel.org
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
			
			
This commit is contained in:
		
							parent
							
								
									b0d75c0809
								
							
						
					
					
						commit
						bcf23c79c4
					
				
					 3 changed files with 31 additions and 4 deletions
				
			
		|  | @ -940,6 +940,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr, | ||||||
| 	if (df->governor == governor) { | 	if (df->governor == governor) { | ||||||
| 		ret = 0; | 		ret = 0; | ||||||
| 		goto out; | 		goto out; | ||||||
|  | 	} else if (df->governor->immutable || governor->immutable) { | ||||||
|  | 		ret = -EINVAL; | ||||||
|  | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (df->governor) { | 	if (df->governor) { | ||||||
|  | @ -969,13 +972,33 @@ static ssize_t available_governors_show(struct device *d, | ||||||
| 					struct device_attribute *attr, | 					struct device_attribute *attr, | ||||||
| 					char *buf) | 					char *buf) | ||||||
| { | { | ||||||
| 	struct devfreq_governor *tmp_governor; | 	struct devfreq *df = to_devfreq(d); | ||||||
| 	ssize_t count = 0; | 	ssize_t count = 0; | ||||||
| 
 | 
 | ||||||
| 	mutex_lock(&devfreq_list_lock); | 	mutex_lock(&devfreq_list_lock); | ||||||
| 	list_for_each_entry(tmp_governor, &devfreq_governor_list, node) | 
 | ||||||
| 		count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), | 	/*
 | ||||||
| 				   "%s ", tmp_governor->name); | 	 * The devfreq with immutable governor (e.g., passive) shows | ||||||
|  | 	 * only own governor. | ||||||
|  | 	 */ | ||||||
|  | 	if (df->governor->immutable) { | ||||||
|  | 		count = scnprintf(&buf[count], DEVFREQ_NAME_LEN, | ||||||
|  | 				   "%s ", df->governor_name); | ||||||
|  | 	/*
 | ||||||
|  | 	 * The devfreq device shows the registered governor except for | ||||||
|  | 	 * immutable governors such as passive governor . | ||||||
|  | 	 */ | ||||||
|  | 	} else { | ||||||
|  | 		struct devfreq_governor *governor; | ||||||
|  | 
 | ||||||
|  | 		list_for_each_entry(governor, &devfreq_governor_list, node) { | ||||||
|  | 			if (governor->immutable) | ||||||
|  | 				continue; | ||||||
|  | 			count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), | ||||||
|  | 					   "%s ", governor->name); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	mutex_unlock(&devfreq_list_lock); | 	mutex_unlock(&devfreq_list_lock); | ||||||
| 
 | 
 | ||||||
| 	/* Truncate the trailing space */ | 	/* Truncate the trailing space */ | ||||||
|  |  | ||||||
|  | @ -179,6 +179,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq, | ||||||
| 
 | 
 | ||||||
| static struct devfreq_governor devfreq_passive = { | static struct devfreq_governor devfreq_passive = { | ||||||
| 	.name = "passive", | 	.name = "passive", | ||||||
|  | 	.immutable = 1, | ||||||
| 	.get_target_freq = devfreq_passive_get_target_freq, | 	.get_target_freq = devfreq_passive_get_target_freq, | ||||||
| 	.event_handler = devfreq_passive_event_handler, | 	.event_handler = devfreq_passive_event_handler, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -104,6 +104,8 @@ struct devfreq_dev_profile { | ||||||
|  * struct devfreq_governor - Devfreq policy governor |  * struct devfreq_governor - Devfreq policy governor | ||||||
|  * @node:		list node - contains registered devfreq governors |  * @node:		list node - contains registered devfreq governors | ||||||
|  * @name:		Governor's name |  * @name:		Governor's name | ||||||
|  |  * @immutable:		Immutable flag for governor. If the value is 1, | ||||||
|  |  *			this govenror is never changeable to other governor. | ||||||
|  * @get_target_freq:	Returns desired operating frequency for the device. |  * @get_target_freq:	Returns desired operating frequency for the device. | ||||||
|  *			Basically, get_target_freq will run |  *			Basically, get_target_freq will run | ||||||
|  *			devfreq_dev_profile.get_dev_status() to get the |  *			devfreq_dev_profile.get_dev_status() to get the | ||||||
|  | @ -121,6 +123,7 @@ struct devfreq_governor { | ||||||
| 	struct list_head node; | 	struct list_head node; | ||||||
| 
 | 
 | ||||||
| 	const char name[DEVFREQ_NAME_LEN]; | 	const char name[DEVFREQ_NAME_LEN]; | ||||||
|  | 	const unsigned int immutable; | ||||||
| 	int (*get_target_freq)(struct devfreq *this, unsigned long *freq); | 	int (*get_target_freq)(struct devfreq *this, unsigned long *freq); | ||||||
| 	int (*event_handler)(struct devfreq *devfreq, | 	int (*event_handler)(struct devfreq *devfreq, | ||||||
| 				unsigned int event, void *data); | 				unsigned int event, void *data); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Chanwoo Choi
						Chanwoo Choi