static void tmu_monitor(struct work_struct *work) { struct delayed_work *delayed_work = to_delayed_work(work); struct tmu_info *info = container_of(delayed_work, struct tmu_info, polling); struct tmu_data *data = info->dev->platform_data; int cur_temp; cur_temp = get_cur_temp(info); dev_dbg(info->dev, "Current: %dc, FLAG=%d\n", cur_temp, info->tmu_state); mutex_lock(&tmu_lock); switch (info->tmu_state) { case TMU_STATUS_NORMAL: exynos_thermal_unthrottle(); enable_irq(info->irq); goto out; case TMU_STATUS_THROTTLED: if (cur_temp >= data->ts.start_tripping) info->tmu_state = TMU_STATUS_TRIPPED; else if (cur_temp > data->ts.stop_throttle) exynos_thermal_throttle(); else info->tmu_state = TMU_STATUS_NORMAL; break; case TMU_STATUS_TRIPPED: if (cur_temp >= data->ts.start_emergency) panic("Emergency thermal shutdown: temp=%d\n", cur_temp); if (cur_temp >= data->ts.start_tripping) { pr_err("thermal tripped: temp=%d\n", cur_temp); /* Throttle twice while tripping */ exynos_thermal_throttle(); } else { info->tmu_state = TMU_STATUS_THROTTLED; } /* Throttle when tripped */ exynos_thermal_throttle(); break; default: break; } queue_delayed_work_on(0, tmu_monitor_wq, &info->polling, info->sampling_rate); out: mutex_unlock(&tmu_lock); }
static void tmu_monitor(struct work_struct *work) { struct delayed_work *delayed_work = to_delayed_work(work); struct tmu_info *info = container_of(delayed_work, struct tmu_info, polling); struct tmu_data *data = info->dev->platform_data; int cur_temp; cur_temp = get_cur_temp(info); dev_dbg(info->dev, "Current: %dc, FLAG=%d\n", cur_temp, info->tmu_state); mutex_lock(&tmu_lock); switch (info->tmu_state) { case TMU_STATUS_NORMAL: exynos_thermal_unthrottle(); enable_irq(info->irq); goto out; case TMU_STATUS_THROTTLED: if (cur_temp >= data->ts.start_tripping) info->tmu_state = TMU_STATUS_TRIPPED; else if (cur_temp > data->ts.stop_throttle) exynos_thermal_throttle(); else info->tmu_state = TMU_STATUS_NORMAL; break; case TMU_STATUS_TRIPPED: if (cur_temp >= data->ts.start_emergency) panic("Emergency thermal shutdown: temp=%d\n", cur_temp); if (cur_temp >= data->ts.start_tripping) pr_err("thermal tripped: temp=%d\n", cur_temp); else info->tmu_state = TMU_STATUS_THROTTLED; break; default: break; } /* Memory throttling */ if (cur_temp >= data->ts.start_mem_throttle && !info->mem_throttled) { set_refresh_period(FREQ_IN_PLL, info->auto_refresh_mem_throttle); info->mem_throttled = true; dev_dbg(info->dev, "set auto refresh period %dns\n", info->auto_refresh_mem_throttle); } else if (cur_temp <= data->ts.stop_mem_throttle && info->mem_throttled) { set_refresh_period(FREQ_IN_PLL, info->auto_refresh_normal); info->mem_throttled = false; dev_dbg(info->dev, "set auto refresh period %dns\n", info->auto_refresh_normal); } queue_delayed_work_on(0, tmu_monitor_wq, &info->polling, info->sampling_rate); out: mutex_unlock(&tmu_lock); }