Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.9 133 lines 3.9 kB view raw
1/* 2 * fair_share.c - A simple weight based Thermal governor 3 * 4 * Copyright (C) 2012 Intel Corp 5 * Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com> 6 * 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; version 2 of the License. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 21 * 22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 */ 24 25#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 26 27#include <linux/module.h> 28#include <linux/thermal.h> 29 30#include "thermal_core.h" 31 32/** 33 * get_trip_level: - obtains the current trip level for a zone 34 * @tz: thermal zone device 35 */ 36static int get_trip_level(struct thermal_zone_device *tz) 37{ 38 int count = 0; 39 unsigned long trip_temp; 40 41 if (tz->trips == 0 || !tz->ops->get_trip_temp) 42 return 0; 43 44 for (count = 0; count < tz->trips; count++) { 45 tz->ops->get_trip_temp(tz, count, &trip_temp); 46 if (tz->temperature < trip_temp) 47 break; 48 } 49 return count; 50} 51 52static long get_target_state(struct thermal_zone_device *tz, 53 struct thermal_cooling_device *cdev, int weight, int level) 54{ 55 unsigned long max_state; 56 57 cdev->ops->get_max_state(cdev, &max_state); 58 59 return (long)(weight * level * max_state) / (100 * tz->trips); 60} 61 62/** 63 * fair_share_throttle - throttles devices asscciated with the given zone 64 * @tz - thermal_zone_device 65 * 66 * Throttling Logic: This uses three parameters to calculate the new 67 * throttle state of the cooling devices associated with the given zone. 68 * 69 * Parameters used for Throttling: 70 * P1. max_state: Maximum throttle state exposed by the cooling device. 71 * P2. weight[i]/100: 72 * How 'effective' the 'i'th device is, in cooling the given zone. 73 * P3. cur_trip_level/max_no_of_trips: 74 * This describes the extent to which the devices should be throttled. 75 * We do not want to throttle too much when we trip a lower temperature, 76 * whereas the throttling is at full swing if we trip critical levels. 77 * (Heavily assumes the trip points are in ascending order) 78 * new_state of cooling device = P3 * P2 * P1 79 */ 80static int fair_share_throttle(struct thermal_zone_device *tz, int trip) 81{ 82 const struct thermal_zone_params *tzp; 83 struct thermal_cooling_device *cdev; 84 struct thermal_instance *instance; 85 int i; 86 int cur_trip_level = get_trip_level(tz); 87 88 if (!tz->tzp || !tz->tzp->tbp) 89 return -EINVAL; 90 91 tzp = tz->tzp; 92 93 for (i = 0; i < tzp->num_tbps; i++) { 94 if (!tzp->tbp[i].cdev) 95 continue; 96 97 cdev = tzp->tbp[i].cdev; 98 instance = get_thermal_instance(tz, cdev, trip); 99 if (!instance) 100 continue; 101 102 instance->target = get_target_state(tz, cdev, 103 tzp->tbp[i].weight, cur_trip_level); 104 105 instance->cdev->updated = false; 106 thermal_cdev_update(cdev); 107 } 108 return 0; 109} 110 111static struct thermal_governor thermal_gov_fair_share = { 112 .name = "fair_share", 113 .throttle = fair_share_throttle, 114 .owner = THIS_MODULE, 115}; 116 117static int __init thermal_gov_fair_share_init(void) 118{ 119 return thermal_register_governor(&thermal_gov_fair_share); 120} 121 122static void __exit thermal_gov_fair_share_exit(void) 123{ 124 thermal_unregister_governor(&thermal_gov_fair_share); 125} 126 127/* This should load after thermal framework */ 128fs_initcall(thermal_gov_fair_share_init); 129module_exit(thermal_gov_fair_share_exit); 130 131MODULE_AUTHOR("Durgadoss R"); 132MODULE_DESCRIPTION("A simple weight based thermal throttling governor"); 133MODULE_LICENSE("GPL");