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; }
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; }