void change_booster_level_for_pen(unsigned char level) { struct booster_dvfs *dvfs = NULL; struct input_booster *data = NULL; if (!g_data) { pr_err("%s: booster is not loaded\n", __func__); return; } dvfs = g_data->dvfses[BOOSTER_DEVICE_PEN]; if (!dvfs || !dvfs->initialized) { DVFS_DEV_DBG(DBG_DVFS, g_data->dev, "%s: Dvfs is not initialized\n", __func__); return; } data = dev_get_drvdata(dvfs->parent_dev); mutex_lock(&dvfs->lock); dvfs->level = level; DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s: %s's LEVEL [%d]\n", __func__, dvfs->name, dvfs->level); mutex_unlock(&dvfs->lock); }
/* Pen */ DECLARE_DVFS_DELAYED_WORK_FUNC(CHG, PEN) { struct input_booster *data = container_of(work, struct input_booster, dvfses[BOOSTER_DEVICE_PEN].dvfs_chg_work.work); struct booster_dvfs *dvfs = &data->dvfses[BOOSTER_DEVICE_PEN]; mutex_lock(&dvfs->lock); switch (dvfs->level) { case BOOSTER_LEVEL0: case BOOSTER_LEVEL1: case BOOSTER_LEVEL3: remove_qos(&dvfs->cpu_qos); remove_qos(&dvfs->mif_qos); remove_qos(&dvfs->int_qos); dvfs->lock_status = false; DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS OFF\n", __func__); break; case BOOSTER_LEVEL2: set_qos(&dvfs->cpu_qos, PM_QOS_CPU_FREQ_MIN, dvfs->freqs[BOOSTER_LEVEL2].cpu_freq); set_qos(&dvfs->mif_qos, PM_QOS_BUS_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL2].mif_freq); set_qos(&dvfs->int_qos, PM_QOS_DEVICE_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL2].int_freq); DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS CHANGED [level %d]\n", __func__, dvfs->level); break; default: dev_err(data->dev, "%s : Undefined type passed[%d]\n", __func__, dvfs->level); break; } mutex_unlock(&dvfs->lock); }
static void input_booster_set_hmp_boost(struct input_booster *data, enum booster_device_type device_type, bool enable) { int retval = 0; struct booster_dvfs *dvfs = NULL; if (device_type >= BOOSTER_DEVICE_MAX) { dev_err(data->dev, "%s : Undefined Device type[%d].\n", __func__, device_type); return; } dvfs = data->dvfses[device_type]; if (!dvfs || !dvfs->initialized) { dev_err(data->dev, "%s : Device %s is not initialized.\n", __func__, booster_device_name[device_type]); return; } if (enable == dvfs->hmp_boosted) { DVFS_DEV_DBG(DBG_MISC, data->dev, "%s : HMP already %s for %s.\n", __func__, enable ? "Enabled" : "Disabled", booster_device_name[device_type]); return; } retval = set_hmp_semiboost(enable); if (retval < 0) { dev_err(data->dev, "%s : Fail to %s HMP[%d] for %s.\n", __func__, enable ? "Enabled" : "Disabled", retval, booster_device_name[device_type]); return; } dvfs->hmp_boosted = enable; DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : HMP %s for %s.\n", __func__, enable ? "Enabled" : "Disabled",booster_device_name[device_type]); }
static void input_booster_event_work(struct work_struct *work) { struct input_booster *data = container_of(work, struct input_booster, event_work); struct booster_event event; int i; for (i = 0; data->front != data->rear; i++) { spin_lock(&data->buffer_lock); event = data->buffer[data->front]; data->front = (data->front + 1) % data->buffer_size; spin_unlock(&data->buffer_lock); DVFS_DEV_DBG(DBG_EVENT, data->dev, "%s :[%d] Device type[%s] mode[%d]\n", __func__, i, booster_device_name[event.device_type], event.mode); switch (event.device_type) { case BOOSTER_DEVICE_KEY: DVFS_WORK_FUNC(SET, KEY)(data, event.mode); break; case BOOSTER_DEVICE_TOUCHKEY: DVFS_WORK_FUNC(SET, TOUCHKEY)(data, event.mode); break; case BOOSTER_DEVICE_TOUCH: DVFS_WORK_FUNC(SET, TOUCH)(data, event.mode); break; case BOOSTER_DEVICE_PEN: DVFS_WORK_FUNC(SET, PEN)(data, event.mode); break; default: break; } } }
/* Touchkey */ DECLARE_DVFS_DELAYED_WORK_FUNC(CHG, TOUCHKEY) { struct input_booster *data = container_of(work, struct input_booster, dvfses[BOOSTER_DEVICE_TOUCHKEY].dvfs_chg_work.work); struct booster_dvfs *dvfs = &data->dvfses[BOOSTER_DEVICE_TOUCHKEY]; mutex_lock(&dvfs->lock); if (dvfs->level == BOOSTER_LEVEL1) { set_qos(&dvfs->cpu_qos, PM_QOS_CPU_FREQ_MIN, dvfs->freqs[BOOSTER_LEVEL1].cpu_freq); set_qos(&dvfs->mif_qos, PM_QOS_BUS_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL1].mif_freq); set_qos(&dvfs->int_qos, PM_QOS_DEVICE_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL1].int_freq); } else { set_qos(&dvfs->cpu_qos, PM_QOS_CPU_FREQ_MIN, dvfs->freqs[BOOSTER_LEVEL2].cpu_freq); set_qos(&dvfs->mif_qos, PM_QOS_BUS_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL2].mif_freq); set_qos(&dvfs->int_qos, PM_QOS_DEVICE_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL2].int_freq); } dvfs->lock_status = true; dvfs->short_press = false; DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS ON [level %d]\n", __func__, dvfs->level); mutex_unlock(&dvfs->lock); }
DECLARE_DVFS_WORK_FUNC(SET, PEN) { struct input_booster *data = (struct input_booster *)booster_data; struct booster_dvfs *dvfs = &data->dvfses[BOOSTER_DEVICE_PEN]; mutex_lock(&dvfs->lock); if (!dvfs->level) { dev_err(data->dev, "%s : Skip to set booster due to level 0\n", __func__); goto out; } switch (booster_mode) { case BOOSTER_MODE_ON: cancel_delayed_work(&dvfs->dvfs_off_work); cancel_delayed_work(&dvfs->dvfs_chg_work); switch (dvfs->level) { case BOOSTER_LEVEL1: case BOOSTER_LEVEL2: set_qos(&dvfs->cpu_qos, PM_QOS_CPU_FREQ_MIN, dvfs->freqs[BOOSTER_LEVEL1].cpu_freq); set_qos(&dvfs->mif_qos, PM_QOS_BUS_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL1].mif_freq); set_qos(&dvfs->int_qos, PM_QOS_DEVICE_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL1].int_freq); break; case BOOSTER_LEVEL3: set_qos(&dvfs->cpu_qos, PM_QOS_CPU_FREQ_MIN, dvfs->freqs[BOOSTER_LEVEL3].cpu_freq); set_qos(&dvfs->mif_qos, PM_QOS_BUS_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL3].mif_freq); set_qos(&dvfs->int_qos, PM_QOS_DEVICE_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL3].int_freq); break; default: dev_err(data->dev, "%s : Undefined type passed[%d]\n", __func__, dvfs->level); break; } DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS ON [level %d]\n", __func__, dvfs->level); schedule_delayed_work(&dvfs->dvfs_chg_work, msecs_to_jiffies(dvfs->msec_chg_time)); dvfs->lock_status = true; break; case BOOSTER_MODE_OFF: if (dvfs->lock_status) schedule_delayed_work(&dvfs->dvfs_off_work, msecs_to_jiffies(dvfs->msec_off_time)); break; case BOOSTER_MODE_FORCE_OFF: if (dvfs->lock_status) { cancel_delayed_work(&dvfs->dvfs_chg_work); cancel_delayed_work(&dvfs->dvfs_off_work); schedule_work(&dvfs->dvfs_off_work.work); } break; default: break; } out: mutex_unlock(&dvfs->lock); return; }
DECLARE_DVFS_DELAYED_WORK_FUNC(OFF, PEN) { struct input_booster *data = container_of(work, struct input_booster, dvfses[BOOSTER_DEVICE_PEN].dvfs_off_work.work); struct booster_dvfs *dvfs = &data->dvfses[BOOSTER_DEVICE_PEN]; mutex_lock(&dvfs->lock); remove_qos(&dvfs->cpu_qos); remove_qos(&dvfs->mif_qos); remove_qos(&dvfs->int_qos); dvfs->lock_status = false; DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS OFF\n", __func__); mutex_unlock(&dvfs->lock); }
DECLARE_DVFS_DELAYED_WORK_FUNC(OFF, PEN) { struct booster_dvfs *dvfs = container_of(work, struct booster_dvfs, dvfs_off_work.work); struct input_booster *data = dev_get_drvdata(dvfs->parent_dev); mutex_lock(&dvfs->lock); remove_qos(&dvfs->cpu_qos); remove_qos(&dvfs->mif_qos); remove_qos(&dvfs->int_qos); dvfs->lock_status = false; DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS OFF\n", __func__); mutex_unlock(&dvfs->lock); }
DECLARE_DVFS_DELAYED_WORK_FUNC(OFF, TOUCH) { struct booster_dvfs *dvfs = container_of(work, struct booster_dvfs, dvfs_off_work.work); struct input_booster *data = dev_get_drvdata(dvfs->parent_dev); mutex_lock(&dvfs->lock); if (dvfs->lock_status) { remove_qos(&dvfs->cpu_qos); remove_qos(&dvfs->kfc_qos); remove_qos(&dvfs->mif_qos); remove_qos(&dvfs->int_qos); SET_HMP(data, BOOSTER_DEVICE_TOUCH, false); dvfs->lock_status = false; dvfs->phase_excuted = false; DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS OFF\n", __func__); } mutex_unlock(&dvfs->lock); }
/* Touch */ DECLARE_DVFS_DELAYED_WORK_FUNC(CHG, TOUCH) { struct booster_dvfs *dvfs = container_of(work, struct booster_dvfs, dvfs_chg_work.work); struct input_booster *data = dev_get_drvdata(dvfs->parent_dev); mutex_lock(&dvfs->lock); if (!dvfs->times[dvfs->level].phase_time) dvfs->phase_excuted = false; switch (dvfs->level) { case BOOSTER_LEVEL0: case BOOSTER_LEVEL1: case BOOSTER_LEVEL3: remove_qos(&dvfs->cpu_qos); remove_qos(&dvfs->kfc_qos); remove_qos(&dvfs->mif_qos); remove_qos(&dvfs->int_qos); SET_HMP(data, BOOSTER_DEVICE_TOUCH, false); dvfs->lock_status = false; DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS OFF\n", __func__); break; case BOOSTER_LEVEL2: set_qos(&dvfs->kfc_qos, PM_QOS_KFC_FREQ_MIN, dvfs->freqs[BOOSTER_LEVEL2].kfc_freq); set_qos(&dvfs->int_qos, PM_QOS_DEVICE_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL2].int_freq); set_qos(&dvfs->mif_qos, PM_QOS_BUS_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL2].mif_freq); remove_qos(&dvfs->cpu_qos); SET_HMP(data, BOOSTER_DEVICE_TOUCH, false); DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS CHANGED [level %d]\n", __func__, dvfs->level); break; case BOOSTER_LEVEL4: DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS CHANGED [level %d]\n", __func__, dvfs->level); break; case BOOSTER_LEVEL5: if (dvfs->phase_excuted) { remove_qos(&dvfs->cpu_qos); remove_qos(&dvfs->kfc_qos); remove_qos(&dvfs->mif_qos); remove_qos(&dvfs->int_qos); SET_HMP(data, BOOSTER_DEVICE_TOUCH, false); dvfs->lock_status = false; dvfs->phase_excuted = false; DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS OFF\n", __func__); } else { set_qos(&dvfs->cpu_qos, PM_QOS_CPU_FREQ_MIN, dvfs->freqs[BOOSTER_LEVEL5].cpu_freq); schedule_delayed_work(&dvfs->dvfs_chg_work, msecs_to_jiffies(dvfs->times[BOOSTER_LEVEL5].head_time - dvfs->times[BOOSTER_LEVEL5].phase_time)); dvfs->phase_excuted = true; DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS CHANGED [level %d, start time[%d]]\n", __func__, dvfs->level, dvfs->times[BOOSTER_LEVEL5].head_time - dvfs->times[BOOSTER_LEVEL5].phase_time); } break; case BOOSTER_LEVEL9: SET_HMP(data, BOOSTER_DEVICE_TOUCH, dvfs->freqs[BOOSTER_LEVEL9_CHG].hmp_boost); set_qos(&dvfs->kfc_qos, PM_QOS_KFC_FREQ_MIN, dvfs->freqs[BOOSTER_LEVEL9_CHG].kfc_freq); set_qos(&dvfs->int_qos, PM_QOS_DEVICE_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL9_CHG].int_freq); set_qos(&dvfs->cpu_qos, PM_QOS_CPU_FREQ_MIN, dvfs->freqs[BOOSTER_LEVEL9_CHG].cpu_freq); set_qos(&dvfs->mif_qos, PM_QOS_BUS_THROUGHPUT, dvfs->freqs[BOOSTER_LEVEL9_CHG].mif_freq); DVFS_DEV_DBG(DBG_DVFS, data->dev, "%s : DVFS CHANGED [level %d]\n", __func__, dvfs->level); break; default: dev_err(data->dev, "%s : Undefined type passed[%d]\n", __func__, dvfs->level); break; } if (!dvfs->lock_status) dvfs->phase_excuted = false; mutex_unlock(&dvfs->lock); }