thermal的gov_bang_bang governer

来源:互联网 发布:扎西拉姆.多多 知乎 编辑:程序博客网 时间:2024/05/21 10:30
thermal gover 有五种,我们这里以gov_bang_bang.c 为例gov_bang_bang是控制风扇的。之后两种状态,即风扇开和关,并没有提供调整风扇转速的方法.static struct thermal_governor thermal_gov_bang_bang = {.name= "bang_bang",.throttle= bang_bang_control,};int thermal_gov_bang_bang_register(void){return thermal_register_governor(&thermal_gov_bang_bang);}thermal_governor的标准写法,可以看到gov本身也提供了bind_to_tz和unbind_from_tz 两个函数指针,但是一般在定义gov的时候只赋值name和throttle,因为zone device注册的时候已经绑定到cool device了struct thermal_governor {char name[THERMAL_NAME_LENGTH];int (*bind_to_tz)(struct thermal_zone_device *tz);void (*unbind_from_tz)(struct thermal_zone_device *tz);int (*throttle)(struct thermal_zone_device *tz, int trip);struct list_headgovernor_list;};这里的throttle 就是gov针对sensor得到的zone device的温度高或者低作出的调整.来看看控制函数throttlestatic int bang_bang_control(struct thermal_zone_device *tz, int trip){struct thermal_instance *instance;//主要是得到下一步需要执行cool device的状态,本里中的状态有两个,即1或者0.来表示风扇的开和关thermal_zone_trip_update(tz, trip);mutex_lock(&tz->lock);// 开始控制风扇的开或者关list_for_each_entry(instance, &tz->thermal_instances, tz_node)thermal_cdev_update(instance->cdev);mutex_unlock(&tz->lock);return 0;}static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip){int trip_temp, trip_hyst;struct thermal_instance *instance;//得到触发点的温度tz->ops->get_trip_temp(tz, trip, &trip_temp);if (!tz->ops->get_trip_hyst) {pr_warn_once("Undefined get_trip_hyst for thermal zone %s - ""running with default hysteresis zero\n", tz->type);trip_hyst = 0;} else//得通过zone device的sensor得到目前的温度tz->ops->get_trip_hyst(tz, trip, &trip_hyst);dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d\n",trip, trip_temp, tz->temperature,trip_hyst);mutex_lock(&tz->lock);list_for_each_entry(instance, &tz->thermal_instances, tz_node) {if (instance->trip != trip)continue;/* in case fan is in initial state, switch the fan off */if (instance->target == THERMAL_NO_TARGET)instance->target = 0;/* in case fan is neither on nor off set the fan to active */if (instance->target != 0 && instance->target != 1) {pr_warn("Thermal instance %s controlled by bang-bang has unexpected state: %ld\n",instance->name, instance->target);instance->target = 1;}/* * enable fan when temperature exceeds trip_temp and disable * the fan in case it falls below trip_temp minus hysteresis *///这里是判断的核心,如果目前得到的温度,已经大于触发点的温度了,说明zone device已经过热了,需要开启风扇,当前前提条件是风扇是关的if (instance->target == 0 && tz->temperature >= trip_temp)instance->target = 1;else if (instance->target == 1 &&tz->temperature <= trip_temp - trip_hyst)instance->target = 0;dev_dbg(&instance->cdev->device, "target=%d\n",(int)instance->target);//从list_for_each_entry 来是到这里主要决定instance->target是0还是1.来决定需要设施风扇是关还是开mutex_lock(&instance->cdev->lock);instance->cdev->updated = false; /* cdev needs update */mutex_unlock(&instance->cdev->lock);}mutex_unlock(&tz->lock);}从thermal_zone_trip_update的到instance->target 后就要调用bang_bang_control函数中的list_for_each_entry(instance, &tz->thermal_instances, tz_node)thermal_cdev_update(instance->cdev);来实际控制风扇void thermal_cdev_update(struct thermal_cooling_device *cdev){struct thermal_instance *instance;unsigned long target = 0;mutex_lock(&cdev->lock);/* cooling device is updated*/if (cdev->updated) {mutex_unlock(&cdev->lock);return;}/* Make sure cdev enters the deepest cooling state */list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {dev_dbg(&cdev->device, "zone%d->target=%lu\n",instance->tz->id, instance->target);if (instance->target == THERMAL_NO_TARGET)continue;if (instance->target > target)target = instance->target;}//核心是这句cdev->ops->set_cur_state(cdev, target);cdev->updated = true;mutex_unlock(&cdev->lock);trace_cdev_update(cdev, target);dev_dbg(&cdev->device, "set to state %lu\n", target);}风扇作为cool device是在drivers/acpi/fan.c中定义的static const struct thermal_cooling_device_ops fan_cooling_ops = {.get_max_state = fan_get_max_state,.get_cur_state = fan_get_cur_state,.set_cur_state = fan_set_cur_state,};可以看到关键的code是fan_set_cur_statestatic intfan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state){struct acpi_device *device = cdev->devdata;struct acpi_fan *fan = acpi_driver_data(device);if (fan->acpi4)return fan_set_state_acpi4(device, state);elsereturn fan_set_state(device, state); }假如这里fan->acpi4为0,则static int fan_set_state(struct acpi_device *device, unsigned long state){if (state != 0 && state != 1)return -EINVAL;//可见最终通过acpi_device_set_power 来设置fan device是ACPI_STATE_D0(开风扇) 还是 ACPI_STATE_D3_COLDreturn acpi_device_set_power(device,     state ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD);}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 耳后总是长孑子怎么办 孩孑高三总是玩手机怎么办 摩托车被收了怎么办 摩托车的手续都怎么办 摩托车罚单掉了怎么办 行人遇到黄灯该怎么办 长辈借钱不还怎么办 不绣刚电梯轿壁有凹槽怎么办 电梯下限位故障怎么办 卫生间夏天太热怎么办 07大檐帽变形了怎么办 税务局不批发票怎么办 进项发票太多了怎么办 发票报销联丢失怎么办 发票领用簿没有怎么办 发票购买本遗失怎么办 销售方遗失发票怎么办 增值税发票发票联丢失怎么办 苹果购买发票丢失怎么办 空白增值税发票发票丢失怎么办 网购发票 领购簿怎么办 购物发票丢了怎么办 饭店客人买单要少钱怎么办 发票备注栏写错怎么办 卖房子发票丢失怎么办 发票二维码蓝票怎么办 车祸伤者出院怎么办 微信付款失败怎么办 增值税电子发票没打税号怎么办 买假出租车发票怎么办 纳税号错了怎么办 发票抬头写错怎么办 增值税发票打错顺序怎么办 发票打错了怎么办 电子发票错了怎么办 税率开高了怎么办 增值发票折叠了怎么办 播放器格式不对怎么办 发票弄上油了怎么办 快手视频快进了怎么办? 三星手机没声音怎么办