static void fan_ramping_work_func(struct work_struct *work) { int rru, rrd; int cur_pwm, next_pwm; struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct fan_dev_data *fan_data = container_of(dwork, struct fan_dev_data, fan_ramp_work); if (!fan_data) { dev_err(fan_data->dev, "Fan data is null\n"); return; } mutex_lock(&fan_data->fan_state_lock); cur_pwm = fan_data->fan_cur_pwm; rru = fan_get_rru(cur_pwm, fan_data); rrd = fan_get_rrd(cur_pwm, fan_data); next_pwm = cur_pwm; if (fan_data->next_target_pwm > fan_data->fan_cur_pwm) { fan_data->fan_cur_pwm = fan_data->fan_cur_pwm + rru; next_pwm = min( get_next_higher_pwm(cur_pwm, fan_data), fan_data->fan_cur_pwm); next_pwm = min(fan_data->next_target_pwm, next_pwm); next_pwm = min(fan_data->fan_cap_pwm, next_pwm); } else if (fan_data->next_target_pwm < fan_data->fan_cur_pwm) { fan_data->fan_cur_pwm = fan_data->fan_cur_pwm - rrd; next_pwm = max(get_next_lower_pwm(cur_pwm, fan_data), fan_data->fan_cur_pwm); next_pwm = max(next_pwm, fan_data->next_target_pwm); next_pwm = max(0, next_pwm); } set_pwm_duty_cycle(next_pwm, fan_data); fan_data->fan_cur_pwm = next_pwm; if (fan_data->next_target_pwm != next_pwm) queue_delayed_work(fan_data->workqueue, &(fan_data->fan_ramp_work), msecs_to_jiffies(fan_data->step_time)); mutex_unlock(&fan_data->fan_state_lock); }
static void fan_ramping_work_func(struct work_struct *work) { int rru, rrd, err; int cur_pwm, next_pwm; struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct fan_dev_data *fan_data = container_of(dwork, struct fan_dev_data, fan_ramp_work); if (!fan_data) { dev_err(fan_data->dev, "Fan data is null\n"); return; } mutex_lock(&fan_data->fan_state_lock); cur_pwm = fan_data->fan_cur_pwm; rru = fan_get_rru(cur_pwm, fan_data); rrd = fan_get_rrd(cur_pwm, fan_data); next_pwm = cur_pwm; if (fan_data->next_target_pwm > fan_data->fan_cur_pwm) { fan_data->fan_cur_pwm = fan_data->fan_cur_pwm + rru; next_pwm = min( get_next_higher_pwm(cur_pwm, fan_data), fan_data->fan_cur_pwm); next_pwm = min(fan_data->next_target_pwm, next_pwm); next_pwm = min(fan_data->fan_cap_pwm, next_pwm); } else if (fan_data->next_target_pwm < fan_data->fan_cur_pwm) { fan_data->fan_cur_pwm = fan_data->fan_cur_pwm - rrd; next_pwm = max(get_next_lower_pwm(cur_pwm, fan_data), fan_data->fan_cur_pwm); next_pwm = max(next_pwm, fan_data->next_target_pwm); next_pwm = max(0, next_pwm); } if ((next_pwm != 0) && !(fan_data->is_fan_reg_enabled)) { err = regulator_enable(fan_data->fan_reg); if (err < 0) dev_err(fan_data->dev, " Coudn't enable vdd-fan\n"); else { dev_info(fan_data->dev, " Enabled vdd-fan\n"); fan_data->is_fan_reg_enabled = true; } } if ((next_pwm == 0) && (fan_data->is_fan_reg_enabled)) { err = regulator_disable(fan_data->fan_reg); if (err < 0) dev_err(fan_data->dev, " Couldn't disable vdd-fan\n"); else { dev_info(fan_data->dev, " Disabled vdd-fan\n"); fan_data->is_fan_reg_enabled = false; } } set_pwm_duty_cycle(next_pwm, fan_data); fan_data->fan_cur_pwm = next_pwm; if (fan_data->next_target_pwm != next_pwm) queue_delayed_work(fan_data->workqueue, &(fan_data->fan_ramp_work), msecs_to_jiffies(fan_data->step_time)); mutex_unlock(&fan_data->fan_state_lock); }