static int db8500_cpufreq_cooling_remove(struct platform_device *pdev) { struct thermal_cooling_device *cdev = platform_get_drvdata(pdev); cpufreq_cooling_unregister(cdev); return 0; }
/* Un-Register with the in-kernel thermal management */ static void amlogic_unregister_thermal(struct amlogic_thermal_platform_data *pdata) { if (pdata->therm_dev) thermal_zone_device_unregister(pdata->therm_dev); if (pdata->cpu_cool_dev) cpufreq_cooling_unregister(pdata->cpu_cool_dev); }
/* Un-Register with the in-kernel thermal management */ static void amlogic_unregister_thermal(struct amlogic_thermal_platform_data *pdata) { if (pdata->therm_dev) thermal_zone_device_unregister(pdata->therm_dev); if (pdata->cpu_cool_dev) cpufreq_cooling_unregister(pdata->cpu_cool_dev); pr_info("amlogic: Kernel Thermal management unregistered\n"); }
static int mtk_cpufreq_exit(struct cpufreq_policy *policy) { struct mtk_cpu_dvfs_info *info = policy->driver_data; cpufreq_cooling_unregister(info->cdev); dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table); mtk_cpu_dvfs_info_release(info); kfree(info); return 0; }
static int __exit kona_thermal_remove(struct platform_device *pdev) { struct kona_tmon_thermal *thermal = platform_get_drvdata(pdev); cpufreq_cooling_unregister(thermal->freq_cdev); thermal_zone_device_unregister(thermal->tz); kona_tmon_exit(thermal, false); clk_disable(thermal->tmon_1m_clk); clk_disable(thermal->tmon_apb_clk); return 0; }
static int scpi_cpufreq_exit(struct cpufreq_policy *policy) { struct scpi_data *priv = policy->driver_data; cpufreq_cooling_unregister(priv->cdev); clk_put(priv->clk); dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); kfree(priv); dev_pm_opp_cpumask_remove_table(policy->related_cpus); return 0; }
void exynos4_unregister_thermal(void) { if (th_zone && th_zone->cool_dev) cpufreq_cooling_unregister(); if (th_zone && th_zone->therm_dev) thermal_zone_device_unregister(th_zone->therm_dev); kfree(th_zone); pr_info("Exynos: Kernel Thermal management unregistered\n"); }
static int imx_thermal_remove(struct platform_device *pdev) { struct imx_thermal_data *data = platform_get_drvdata(pdev); struct regmap *map = data->tempmon; /* Disable measurements */ regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); thermal_zone_device_unregister(data->tz); cpufreq_cooling_unregister(data->cdev); return 0; }
static int cpufreq_exit(struct cpufreq_policy *policy) { struct private_data *priv = policy->driver_data; cpufreq_cooling_unregister(priv->cdev); dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); clk_put(policy->clk); if (!IS_ERR(priv->cpu_reg)) regulator_put(priv->cpu_reg); kfree(priv); return 0; }
static int cpufreq_exit(struct cpufreq_policy *policy) { struct private_data *priv = policy->driver_data; cpufreq_cooling_unregister(priv->cdev); dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); dev_pm_opp_of_cpumask_remove_table(policy->related_cpus); if (priv->reg_name) dev_pm_opp_put_regulators(priv->opp_table); clk_put(policy->clk); kfree(priv); return 0; }
/* Un-Register with the in-kernel thermal management */ static void exynos_unregister_thermal(void) { int i; for (i = 0; i < th_zone->cool_dev_size; i++) { if (th_zone && th_zone->cool_dev[i]) cpufreq_cooling_unregister(th_zone->cool_dev[i]); } if (th_zone && th_zone->therm_dev) thermal_zone_device_unregister(th_zone->therm_dev); kfree(th_zone); pr_info("Exynos: Kernel Thermal management unregistered\n"); }
/* Un-Register with the in-kernel thermal management */ void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf) { int i; struct exynos_thermal_zone *th_zone; if (!sensor_conf || !sensor_conf->pzone_data) { pr_err("Invalid temperature sensor configuration data\n"); return; } th_zone = sensor_conf->pzone_data; thermal_zone_device_unregister(th_zone->therm_dev); for (i = 0; i < th_zone->cool_dev_size; ++i) cpufreq_cooling_unregister(th_zone->cool_dev[i]); dev_info(sensor_conf->dev, "Exynos: Kernel Thermal management unregistered\n"); }
static int bL_cpufreq_exit(struct cpufreq_policy *policy) { struct device *cpu_dev; int cur_cluster = cpu_to_cluster(policy->cpu); if (cur_cluster < MAX_CLUSTERS) { cpufreq_cooling_unregister(cdev[cur_cluster]); cdev[cur_cluster] = NULL; } cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { pr_err("%s: failed to get cpu%d device\n", __func__, policy->cpu); return -ENODEV; } put_cluster_clk_and_freq_table(cpu_dev, policy->related_cpus); dev_dbg(cpu_dev, "%s: Exited, cpu: %d\n", __func__, policy->cpu); return 0; }
static int cpufreq_init(struct cpufreq_policy *policy) { struct cpufreq_dt_platform_data *pd; struct cpufreq_frequency_table *freq_table; struct thermal_cooling_device *cdev; struct device_node *np; struct private_data *priv; struct device *cpu_dev; struct regulator *cpu_reg; struct clk *cpu_clk; unsigned long min_uV = ~0, max_uV = 0; unsigned int transition_latency; int ret; ret = allocate_resources(policy->cpu, &cpu_dev, &cpu_reg, &cpu_clk); if (ret) { pr_err("%s: Failed to allocate resources\n: %d", __func__, ret); return ret; } np = of_node_get(cpu_dev->of_node); if (!np) { dev_err(cpu_dev, "failed to find cpu%d node\n", policy->cpu); ret = -ENOENT; goto out_put_reg_clk; } /* OPPs might be populated at runtime, don't check for error here */ of_init_opp_table(cpu_dev); priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { ret = -ENOMEM; goto out_put_node; } of_property_read_u32(np, "voltage-tolerance", &priv->voltage_tolerance); if (of_property_read_u32(np, "clock-latency", &transition_latency)) transition_latency = CPUFREQ_ETERNAL; if (!IS_ERR(cpu_reg)) { unsigned long opp_freq = 0; /* * Disable any OPPs where the connected regulator isn't able to * provide the specified voltage and record minimum and maximum * voltage levels. */ while (1) { struct dev_pm_opp *opp; unsigned long opp_uV, tol_uV; rcu_read_lock(); opp = dev_pm_opp_find_freq_ceil(cpu_dev, &opp_freq); if (IS_ERR(opp)) { rcu_read_unlock(); break; } opp_uV = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); tol_uV = opp_uV * priv->voltage_tolerance / 100; if (regulator_is_supported_voltage(cpu_reg, opp_uV, opp_uV + tol_uV)) { if (opp_uV < min_uV) min_uV = opp_uV; if (opp_uV > max_uV) max_uV = opp_uV; } else { dev_pm_opp_disable(cpu_dev, opp_freq); } opp_freq++; } ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV); if (ret > 0) transition_latency += ret * 1000; } ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); if (ret) { pr_err("failed to init cpufreq table: %d\n", ret); goto out_free_priv; } /* * For now, just loading the cooling device; * thermal DT code takes care of matching them. */ if (of_find_property(np, "#cooling-cells", NULL)) { cdev = of_cpufreq_cooling_register(np, cpu_present_mask); if (IS_ERR(cdev)) dev_err(cpu_dev, "running cpufreq without cooling device: %ld\n", PTR_ERR(cdev)); else priv->cdev = cdev; } priv->cpu_dev = cpu_dev; priv->cpu_reg = cpu_reg; policy->driver_data = priv; policy->clk = cpu_clk; ret = cpufreq_table_validate_and_show(policy, freq_table); if (ret) { dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__, ret); goto out_cooling_unregister; } policy->cpuinfo.transition_latency = transition_latency; pd = cpufreq_get_driver_data(); if (!pd || !pd->independent_clocks) cpumask_setall(policy->cpus); of_node_put(np); return 0; out_cooling_unregister: cpufreq_cooling_unregister(priv->cdev); dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); out_free_priv: kfree(priv); out_put_node: of_node_put(np); out_put_reg_clk: clk_put(cpu_clk); if (!IS_ERR(cpu_reg)) regulator_put(cpu_reg); return ret; }
static int imx_thermal_probe(struct platform_device *pdev) { struct imx_thermal_data *data; struct cpumask clip_cpus; struct regmap *map; int measure_freq; int ret; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon"); if (IS_ERR(map)) { ret = PTR_ERR(map); dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret); return ret; } data->tempmon = map; data->irq = platform_get_irq(pdev, 0); if (data->irq < 0) return data->irq; ret = devm_request_threaded_irq(&pdev->dev, data->irq, imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread, 0, "imx_thermal", data); if (ret < 0) { dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret); return ret; } platform_set_drvdata(pdev, data); ret = imx_get_sensor_data(pdev); if (ret) { dev_err(&pdev->dev, "failed to get sensor data\n"); return ret; } /* Make sure sensor is in known good state for measurements */ regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP); regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); cpumask_set_cpu(0, &clip_cpus); data->cdev = cpufreq_cooling_register(&clip_cpus); if (IS_ERR(data->cdev)) { ret = PTR_ERR(data->cdev); dev_err(&pdev->dev, "failed to register cpufreq cooling device: %d\n", ret); return ret; } data->tz = thermal_zone_device_register("imx_thermal_zone", IMX_TRIP_NUM, BIT(IMX_TRIP_PASSIVE), data, &imx_tz_ops, NULL, IMX_PASSIVE_DELAY, IMX_POLLING_DELAY); if (IS_ERR(data->tz)) { ret = PTR_ERR(data->tz); dev_err(&pdev->dev, "failed to register thermal zone device %d\n", ret); cpufreq_cooling_unregister(data->cdev); return ret; } data->thermal_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(data->thermal_clk)) { dev_warn(&pdev->dev, "failed to get thermal clk!\n"); } else { /* * Thermal sensor needs clk on to get correct value, normally * we should enable its clk before taking measurement and disable * clk after measurement is done, but if alarm function is enabled, * hardware will auto measure the temperature periodically, so we * need to keep the clk always on for alarm function. */ ret = clk_prepare_enable(data->thermal_clk); if (ret) dev_warn(&pdev->dev, "failed to enable thermal clk: %d\n", ret); } /* Enable measurements at ~ 10 Hz */ regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */ regmap_write(map, TEMPSENSE1 + REG_SET, measure_freq); imx_set_alarm_temp(data, data->temp_passive); regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); data->irq_enabled = true; data->mode = THERMAL_DEVICE_ENABLED; return 0; }
static int __init kona_thermal_probe(struct platform_device *pdev) { struct kona_tmon_thermal *thermal; struct kona_tmon_pdata *pdata; int ret = 0; thermal = devm_kzalloc(&pdev->dev, sizeof(*thermal), GFP_KERNEL); if (!thermal) return -ENOMEM; if (pdev->dev.of_node) { pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; ret = kona_tmon_parse_dt(pdev, pdata); if (ret) { tmon_dbg(TMON_LOG_INIT, "error while parsing DT\n"); return ret; } } else { pdata = pdev->dev.platform_data; } if (!pdata) { tmon_dbg(TMON_LOG_INIT, "platform data get failed\n"); return -ENODEV; } thermal->pdata = pdata; ret = devm_request_irq(&pdev->dev, thermal->pdata->irq, kona_tmon_isr, IRQ_LEVEL | IRQF_NO_SUSPEND | IRQF_DISABLED, pdev->name, thermal); if (ret < 0) { tmon_dbg(TMON_LOG_INIT, "irq registration failed\n"); return ret; } thermal->tmon_apb_clk = clk_get(NULL, pdata->tmon_apb_clk); if (IS_ERR(thermal->tmon_apb_clk)) { tmon_dbg(TMON_LOG_INIT, "tmon apb clk get failed\n"); return PTR_ERR(thermal->tmon_apb_clk); } clk_enable(thermal->tmon_apb_clk); thermal->tmon_1m_clk = clk_get(NULL, pdata->tmon_1m_clk); if (IS_ERR(thermal->tmon_1m_clk)) { tmon_dbg(TMON_LOG_INIT, "tmon 1m clk get failed\n"); return PTR_ERR(thermal->tmon_1m_clk); } if (clk_set_rate(thermal->tmon_1m_clk, TMON_1M_CLK_RATE)) { tmon_dbg(TMON_LOG_INIT, "tmon_1m_clk rate set failed\n"); return -EINVAL; } clk_enable(thermal->tmon_1m_clk); mutex_init(&thermal->lock); INIT_WORK(&thermal->isr_work, kona_tmon_irq_work); INIT_DELAYED_WORK(&thermal->polling_work, kona_tmon_polling_work); platform_set_drvdata(pdev, thermal); thermal->active_cnt = kona_tmon_active_trip_cnt(thermal); ret = kona_tmon_init(thermal); if (ret) { tmon_dbg(TMON_LOG_INIT, "tmon configuration failed\n"); goto err_init; } thermal->freq_cdev = cpufreq_cooling_register(cpu_present_mask); if (IS_ERR(thermal->freq_cdev)) { tmon_dbg(TMON_LOG_INIT, "cpufreq cooling dev registration failed\n"); ret = PTR_ERR(thermal->freq_cdev); goto err_cpucool; } thermal->tz = thermal_zone_device_register("tmon", thermal->pdata->trip_cnt, TRIP_UPDATE_MASK, thermal, &tmon_ops, NULL, 0, 0); if (IS_ERR(thermal->tz)) { tmon_dbg(TMON_LOG_INIT, "thermal zone registration failed\n"); ret = PTR_ERR(thermal->tz); goto err_tz_reg; } suspend_poweroff = pdata->flags & TMON_SUSPEND_POWEROFF ? ENABLE_SUSPEND_POWEROFF : DISABLE_SUSPEND_POWEROFF; /* start polling only if cur_idx is greater than zero */ if (thermal->cur_idx) schedule_delayed_work(&thermal->polling_work, msecs_to_jiffies(pdata->poll_rate_ms)); if (kona_tmon_debugfs_init(thermal)) tmon_dbg(TMON_LOG_DBG, "tmon debugfs init failed\n"); return ret; err_tz_reg: cpufreq_cooling_unregister(thermal->freq_cdev); err_cpucool: kona_tmon_exit(thermal, false); err_init: clk_disable(thermal->tmon_1m_clk); clk_disable(thermal->tmon_apb_clk); return ret; }
static int imx_thermal_probe(struct platform_device *pdev) { struct imx_thermal_data *data; struct cpumask clip_cpus; struct regmap *map; int measure_freq; int ret; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon"); if (IS_ERR(map)) { ret = PTR_ERR(map); dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret); return ret; } data->tempmon = map; data->irq = platform_get_irq(pdev, 0); if (data->irq < 0) return data->irq; ret = devm_request_threaded_irq(&pdev->dev, data->irq, imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread, 0, "imx_thermal", data); if (ret < 0) { dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret); return ret; } platform_set_drvdata(pdev, data); ret = imx_get_sensor_data(pdev); if (ret) { dev_err(&pdev->dev, "failed to get sensor data\n"); return ret; } /* Make sure sensor is in known good state for measurements */ regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP); regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); cpumask_set_cpu(0, &clip_cpus); data->cdev = cpufreq_cooling_register(&clip_cpus); if (IS_ERR(data->cdev)) { ret = PTR_ERR(data->cdev); dev_err(&pdev->dev, "failed to register cpufreq cooling device: %d\n", ret); return ret; } data->tz = thermal_zone_device_register("imx_thermal_zone", IMX_TRIP_NUM, BIT(IMX_TRIP_PASSIVE), data, &imx_tz_ops, NULL, IMX_PASSIVE_DELAY, IMX_POLLING_DELAY); if (IS_ERR(data->tz)) { ret = PTR_ERR(data->tz); dev_err(&pdev->dev, "failed to register thermal zone device %d\n", ret); cpufreq_cooling_unregister(data->cdev); return ret; } /* Enable measurements at ~ 10 Hz */ regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */ regmap_write(map, TEMPSENSE1 + REG_SET, measure_freq); imx_set_alarm_temp(data, data->temp_passive); regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); data->irq_enabled = true; data->mode = THERMAL_DEVICE_ENABLED; return 0; }