Lines Matching +full:tmu +full:- +full:calibration
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * exynos_tmu.c - Samsung Exynos TMU (Thermal Management Unit)
24 #include <dt-bindings/thermal/thermal_exynos.h>
140 * struct exynos_tmu_data : A structure to hold the private data of the TMU
142 * @id: identifier of the one instance of the TMU controller.
143 * @base: base address of the single instance of the TMU controller.
144 * @base_second: base address of the common registers of the TMU controller.
145 * @irq: irq number of the TMU controller.
151 * @sclk: pointer to the clock structure for accessing the tmu special clk.
152 * @cal_type: calibration type for temperature
158 * @gain: gain of amplifier in the positive-TC generator block
161 * in the positive-TC generator block
163 * @regulator: pointer to the TMU regulator structure.
167 * @enabled: current status of TMU device
170 * @tmu_initialize: SoC specific TMU initialization method
171 * @tmu_control: SoC specific TMU control method
172 * @tmu_read: SoC specific TMU temperature read method
173 * @tmu_set_emulation: SoC specific TMU emulation setting method
174 * @tmu_clear_irqs: SoC specific TMU interrupts clearing method
209 * TMU treats temperature as a mapped temperature code.
210 * The temperature is converted differently depending on the calibration type.
214 if (data->cal_type == TYPE_ONE_POINT_TRIMMING) in temp_to_code()
215 return temp + data->temp_error1 - EXYNOS_FIRST_POINT_TRIM; in temp_to_code()
217 return (temp - EXYNOS_FIRST_POINT_TRIM) * in temp_to_code()
218 (data->temp_error2 - data->temp_error1) / in temp_to_code()
219 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) + in temp_to_code()
220 data->temp_error1; in temp_to_code()
229 if (data->cal_type == TYPE_ONE_POINT_TRIMMING) in code_to_temp()
230 return temp_code - data->temp_error1 + EXYNOS_FIRST_POINT_TRIM; in code_to_temp()
232 return (temp_code - data->temp_error1) * in code_to_temp()
233 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) / in code_to_temp()
234 (data->temp_error2 - data->temp_error1) + in code_to_temp()
241 (data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK in sanitize_temp_error()
244 data->temp_error1 = trim_info & tmu_temp_mask; in sanitize_temp_error()
245 data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & in sanitize_temp_error()
248 if (!data->temp_error1 || in sanitize_temp_error()
249 (data->min_efuse_value > data->temp_error1) || in sanitize_temp_error()
250 (data->temp_error1 > data->max_efuse_value)) in sanitize_temp_error()
251 data->temp_error1 = data->efuse_value & EXYNOS_TMU_TEMP_MASK; in sanitize_temp_error()
253 if (!data->temp_error2) in sanitize_temp_error()
254 data->temp_error2 = in sanitize_temp_error()
255 (data->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) & in sanitize_temp_error()
262 struct thermal_zone_device *tzd = data->tzd; in exynos_tmu_initialize()
269 dev_err(&pdev->dev, in exynos_tmu_initialize()
271 return -ENODEV; in exynos_tmu_initialize()
274 if (data->soc != SOC_ARCH_EXYNOS5433) /* FIXME */ in exynos_tmu_initialize()
275 ret = tzd->ops->get_crit_temp(tzd, &temp); in exynos_tmu_initialize()
277 dev_err(&pdev->dev, in exynos_tmu_initialize()
282 if (of_thermal_get_ntrips(tzd) > data->ntrip) { in exynos_tmu_initialize()
283 dev_info(&pdev->dev, in exynos_tmu_initialize()
284 "More trip points than supported by this TMU.\n"); in exynos_tmu_initialize()
285 dev_info(&pdev->dev, in exynos_tmu_initialize()
287 (of_thermal_get_ntrips(tzd) - data->ntrip)); in exynos_tmu_initialize()
290 mutex_lock(&data->lock); in exynos_tmu_initialize()
291 clk_enable(data->clk); in exynos_tmu_initialize()
292 if (!IS_ERR(data->clk_sec)) in exynos_tmu_initialize()
293 clk_enable(data->clk_sec); in exynos_tmu_initialize()
295 status = readb(data->base + EXYNOS_TMU_REG_STATUS); in exynos_tmu_initialize()
297 ret = -EBUSY; in exynos_tmu_initialize()
300 min_t(int, of_thermal_get_ntrips(tzd), data->ntrip); in exynos_tmu_initialize()
302 data->tmu_initialize(pdev); in exynos_tmu_initialize()
307 ret = tzd->ops->get_trip_temp(tzd, i, &temp); in exynos_tmu_initialize()
311 data->tmu_set_trip_temp(data, i, temp); in exynos_tmu_initialize()
314 ret = tzd->ops->get_trip_hyst(tzd, i, &hyst); in exynos_tmu_initialize()
318 data->tmu_set_trip_hyst(data, i, temp, hyst); in exynos_tmu_initialize()
321 data->tmu_clear_irqs(data); in exynos_tmu_initialize()
324 clk_disable(data->clk); in exynos_tmu_initialize()
325 mutex_unlock(&data->lock); in exynos_tmu_initialize()
326 if (!IS_ERR(data->clk_sec)) in exynos_tmu_initialize()
327 clk_disable(data->clk_sec); in exynos_tmu_initialize()
334 if (data->soc == SOC_ARCH_EXYNOS4412 || in get_con_reg()
335 data->soc == SOC_ARCH_EXYNOS3250) in get_con_reg()
339 con |= data->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT; in get_con_reg()
342 con |= (data->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT); in get_con_reg()
354 mutex_lock(&data->lock); in exynos_tmu_control()
355 clk_enable(data->clk); in exynos_tmu_control()
356 data->tmu_control(pdev, on); in exynos_tmu_control()
357 data->enabled = on; in exynos_tmu_control()
358 clk_disable(data->clk); in exynos_tmu_control()
359 mutex_unlock(&data->lock); in exynos_tmu_control()
366 of_thermal_get_trip_points(data->tzd); in exynos4210_tmu_set_trip_temp()
373 writeb(th_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); in exynos4210_tmu_set_trip_temp()
376 temp -= ref; in exynos4210_tmu_set_trip_temp()
377 writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip * 4); in exynos4210_tmu_set_trip_temp()
390 sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO)); in exynos4210_tmu_initialize()
398 th = readl(data->base + EXYNOS_THD_TEMP_RISE); in exynos4412_tmu_set_trip_temp()
401 writel(th, data->base + EXYNOS_THD_TEMP_RISE); in exynos4412_tmu_set_trip_temp()
404 con = readl(data->base + EXYNOS_TMU_REG_CONTROL); in exynos4412_tmu_set_trip_temp()
406 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); in exynos4412_tmu_set_trip_temp()
415 th = readl(data->base + EXYNOS_THD_TEMP_FALL); in exynos4412_tmu_set_trip_hyst()
418 th |= temp_to_code(data, temp - hyst) << 8 * trip; in exynos4412_tmu_set_trip_hyst()
419 writel(th, data->base + EXYNOS_THD_TEMP_FALL); in exynos4412_tmu_set_trip_hyst()
427 if (data->soc == SOC_ARCH_EXYNOS3250 || in exynos4412_tmu_initialize()
428 data->soc == SOC_ARCH_EXYNOS4412 || in exynos4412_tmu_initialize()
429 data->soc == SOC_ARCH_EXYNOS5250) { in exynos4412_tmu_initialize()
430 if (data->soc == SOC_ARCH_EXYNOS3250) { in exynos4412_tmu_initialize()
431 ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); in exynos4412_tmu_initialize()
433 writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); in exynos4412_tmu_initialize()
435 ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2); in exynos4412_tmu_initialize()
437 writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2); in exynos4412_tmu_initialize()
441 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) in exynos4412_tmu_initialize()
442 trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO); in exynos4412_tmu_initialize()
444 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); in exynos4412_tmu_initialize()
457 j = trip - 4; in exynos5433_tmu_set_trip_temp()
463 th = readl(data->base + reg_off); in exynos5433_tmu_set_trip_temp()
466 writel(th, data->base + reg_off); in exynos5433_tmu_set_trip_temp()
477 j = trip - 4; in exynos5433_tmu_set_trip_hyst()
483 th = readl(data->base + reg_off); in exynos5433_tmu_set_trip_hyst()
485 th |= (temp_to_code(data, temp - hyst) << j * 8); in exynos5433_tmu_set_trip_hyst()
486 writel(th, data->base + reg_off); in exynos5433_tmu_set_trip_hyst()
495 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); in exynos5433_tmu_initialize()
501 dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id); in exynos5433_tmu_initialize()
503 /* Read the calibration mode */ in exynos5433_tmu_initialize()
504 writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO); in exynos5433_tmu_initialize()
510 data->cal_type = TYPE_TWO_POINT_TRIMMING; in exynos5433_tmu_initialize()
514 data->cal_type = TYPE_ONE_POINT_TRIMMING; in exynos5433_tmu_initialize()
518 dev_info(&pdev->dev, "Calibration type is %d-point calibration\n", in exynos5433_tmu_initialize()
528 reg_off = ((7 - trip) / 2) * 4; in exynos7_tmu_set_trip_temp()
529 bit_off = ((8 - trip) % 2); in exynos7_tmu_set_trip_temp()
531 th = readl(data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off); in exynos7_tmu_set_trip_temp()
534 writel(th, data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off); in exynos7_tmu_set_trip_temp()
543 reg_off = ((7 - trip) / 2) * 4; in exynos7_tmu_set_trip_hyst()
544 bit_off = ((8 - trip) % 2); in exynos7_tmu_set_trip_hyst()
546 th = readl(data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off); in exynos7_tmu_set_trip_hyst()
548 th |= temp_to_code(data, temp - hyst) << (16 * bit_off); in exynos7_tmu_set_trip_hyst()
549 writel(th, data->base + EXYNOS7_THD_TEMP_FALL7_6 + reg_off); in exynos7_tmu_set_trip_hyst()
557 trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); in exynos7_tmu_initialize()
564 struct thermal_zone_device *tz = data->tzd; in exynos4210_tmu_control()
567 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); in exynos4210_tmu_control()
570 for (i = 0; i < data->ntrip; i++) { in exynos4210_tmu_control()
578 if (data->soc != SOC_ARCH_EXYNOS4210) in exynos4210_tmu_control()
587 writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN); in exynos4210_tmu_control()
588 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); in exynos4210_tmu_control()
594 struct thermal_zone_device *tz = data->tzd; in exynos5433_tmu_control()
597 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); in exynos5433_tmu_control()
600 for (i = 0; i < data->ntrip; i++) { in exynos5433_tmu_control()
617 writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN); in exynos5433_tmu_control()
618 writel(interrupt_en, data->base + EXYNOS5433_TMU_REG_INTEN); in exynos5433_tmu_control()
619 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); in exynos5433_tmu_control()
625 struct thermal_zone_device *tz = data->tzd; in exynos7_tmu_control()
628 con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); in exynos7_tmu_control()
631 for (i = 0; i < data->ntrip; i++) { in exynos7_tmu_control()
649 writel(interrupt_en, data->base + EXYNOS7_TMU_REG_INTEN); in exynos7_tmu_control()
650 writel(con, data->base + EXYNOS_TMU_REG_CONTROL); in exynos7_tmu_control()
658 if (!data || !data->tmu_read) in exynos_get_temp()
659 return -EINVAL; in exynos_get_temp()
660 else if (!data->enabled) in exynos_get_temp()
665 return -EAGAIN; in exynos_get_temp()
667 mutex_lock(&data->lock); in exynos_get_temp()
668 clk_enable(data->clk); in exynos_get_temp()
670 value = data->tmu_read(data); in exynos_get_temp()
676 clk_disable(data->clk); in exynos_get_temp()
677 mutex_unlock(&data->lock); in exynos_get_temp()
691 if (data->soc == SOC_ARCH_EXYNOS7) { in get_emul_con_reg()
717 if (data->soc == SOC_ARCH_EXYNOS5260) in exynos4412_tmu_set_emulation()
719 else if (data->soc == SOC_ARCH_EXYNOS5433) in exynos4412_tmu_set_emulation()
721 else if (data->soc == SOC_ARCH_EXYNOS7) in exynos4412_tmu_set_emulation()
726 val = readl(data->base + emul_con); in exynos4412_tmu_set_emulation()
728 writel(val, data->base + emul_con); in exynos4412_tmu_set_emulation()
734 int ret = -EINVAL; in exynos_tmu_set_emulation()
736 if (data->soc == SOC_ARCH_EXYNOS4210) in exynos_tmu_set_emulation()
742 mutex_lock(&data->lock); in exynos_tmu_set_emulation()
743 clk_enable(data->clk); in exynos_tmu_set_emulation()
744 data->tmu_set_emulation(data, temp); in exynos_tmu_set_emulation()
745 clk_disable(data->clk); in exynos_tmu_set_emulation()
746 mutex_unlock(&data->lock); in exynos_tmu_set_emulation()
754 { return -EINVAL; } in exynos_tmu_set_emulation()
759 int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); in exynos4210_tmu_read()
762 return (ret < 75 || ret > 175) ? -ENODATA : ret; in exynos4210_tmu_read()
767 return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); in exynos4412_tmu_read()
772 return readw(data->base + EXYNOS_TMU_REG_CURRENT_TEMP) & in exynos7_tmu_read()
781 thermal_zone_device_update(data->tzd, THERMAL_EVENT_UNSPECIFIED); in exynos_tmu_work()
783 mutex_lock(&data->lock); in exynos_tmu_work()
784 clk_enable(data->clk); in exynos_tmu_work()
787 data->tmu_clear_irqs(data); in exynos_tmu_work()
789 clk_disable(data->clk); in exynos_tmu_work()
790 mutex_unlock(&data->lock); in exynos_tmu_work()
791 enable_irq(data->irq); in exynos_tmu_work()
799 if (data->soc == SOC_ARCH_EXYNOS5260) { in exynos4210_tmu_clear_irqs()
802 } else if (data->soc == SOC_ARCH_EXYNOS7) { in exynos4210_tmu_clear_irqs()
805 } else if (data->soc == SOC_ARCH_EXYNOS5433) { in exynos4210_tmu_clear_irqs()
813 val_irq = readl(data->base + tmu_intstat); in exynos4210_tmu_clear_irqs()
822 writel(val_irq, data->base + tmu_intclear); in exynos4210_tmu_clear_irqs()
830 schedule_work(&data->irq_work); in exynos_tmu_irq()
837 .compatible = "samsung,exynos3250-tmu",
840 .compatible = "samsung,exynos4210-tmu",
843 .compatible = "samsung,exynos4412-tmu",
846 .compatible = "samsung,exynos5250-tmu",
849 .compatible = "samsung,exynos5260-tmu",
852 .compatible = "samsung,exynos5420-tmu",
855 .compatible = "samsung,exynos5420-tmu-ext-triminfo",
858 .compatible = "samsung,exynos5433-tmu",
861 .compatible = "samsung,exynos7-tmu",
873 if (!data || !pdev->dev.of_node) in exynos_map_dt_data()
874 return -ENODEV; in exynos_map_dt_data()
876 data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl"); in exynos_map_dt_data()
877 if (data->id < 0) in exynos_map_dt_data()
878 data->id = 0; in exynos_map_dt_data()
880 data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); in exynos_map_dt_data()
881 if (data->irq <= 0) { in exynos_map_dt_data()
882 dev_err(&pdev->dev, "failed to get IRQ\n"); in exynos_map_dt_data()
883 return -ENODEV; in exynos_map_dt_data()
886 if (of_address_to_resource(pdev->dev.of_node, 0, &res)) { in exynos_map_dt_data()
887 dev_err(&pdev->dev, "failed to get Resource 0\n"); in exynos_map_dt_data()
888 return -ENODEV; in exynos_map_dt_data()
891 data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); in exynos_map_dt_data()
892 if (!data->base) { in exynos_map_dt_data()
893 dev_err(&pdev->dev, "Failed to ioremap memory\n"); in exynos_map_dt_data()
894 return -EADDRNOTAVAIL; in exynos_map_dt_data()
897 data->soc = (enum soc_type)of_device_get_match_data(&pdev->dev); in exynos_map_dt_data()
899 switch (data->soc) { in exynos_map_dt_data()
901 data->tmu_set_trip_temp = exynos4210_tmu_set_trip_temp; in exynos_map_dt_data()
902 data->tmu_set_trip_hyst = exynos4210_tmu_set_trip_hyst; in exynos_map_dt_data()
903 data->tmu_initialize = exynos4210_tmu_initialize; in exynos_map_dt_data()
904 data->tmu_control = exynos4210_tmu_control; in exynos_map_dt_data()
905 data->tmu_read = exynos4210_tmu_read; in exynos_map_dt_data()
906 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; in exynos_map_dt_data()
907 data->ntrip = 4; in exynos_map_dt_data()
908 data->gain = 15; in exynos_map_dt_data()
909 data->reference_voltage = 7; in exynos_map_dt_data()
910 data->efuse_value = 55; in exynos_map_dt_data()
911 data->min_efuse_value = 40; in exynos_map_dt_data()
912 data->max_efuse_value = 100; in exynos_map_dt_data()
920 data->tmu_set_trip_temp = exynos4412_tmu_set_trip_temp; in exynos_map_dt_data()
921 data->tmu_set_trip_hyst = exynos4412_tmu_set_trip_hyst; in exynos_map_dt_data()
922 data->tmu_initialize = exynos4412_tmu_initialize; in exynos_map_dt_data()
923 data->tmu_control = exynos4210_tmu_control; in exynos_map_dt_data()
924 data->tmu_read = exynos4412_tmu_read; in exynos_map_dt_data()
925 data->tmu_set_emulation = exynos4412_tmu_set_emulation; in exynos_map_dt_data()
926 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; in exynos_map_dt_data()
927 data->ntrip = 4; in exynos_map_dt_data()
928 data->gain = 8; in exynos_map_dt_data()
929 data->reference_voltage = 16; in exynos_map_dt_data()
930 data->efuse_value = 55; in exynos_map_dt_data()
931 if (data->soc != SOC_ARCH_EXYNOS5420 && in exynos_map_dt_data()
932 data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO) in exynos_map_dt_data()
933 data->min_efuse_value = 40; in exynos_map_dt_data()
935 data->min_efuse_value = 0; in exynos_map_dt_data()
936 data->max_efuse_value = 100; in exynos_map_dt_data()
939 data->tmu_set_trip_temp = exynos5433_tmu_set_trip_temp; in exynos_map_dt_data()
940 data->tmu_set_trip_hyst = exynos5433_tmu_set_trip_hyst; in exynos_map_dt_data()
941 data->tmu_initialize = exynos5433_tmu_initialize; in exynos_map_dt_data()
942 data->tmu_control = exynos5433_tmu_control; in exynos_map_dt_data()
943 data->tmu_read = exynos4412_tmu_read; in exynos_map_dt_data()
944 data->tmu_set_emulation = exynos4412_tmu_set_emulation; in exynos_map_dt_data()
945 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; in exynos_map_dt_data()
946 data->ntrip = 8; in exynos_map_dt_data()
947 data->gain = 8; in exynos_map_dt_data()
949 data->reference_voltage = 23; in exynos_map_dt_data()
951 data->reference_voltage = 16; in exynos_map_dt_data()
952 data->efuse_value = 75; in exynos_map_dt_data()
953 data->min_efuse_value = 40; in exynos_map_dt_data()
954 data->max_efuse_value = 150; in exynos_map_dt_data()
957 data->tmu_set_trip_temp = exynos7_tmu_set_trip_temp; in exynos_map_dt_data()
958 data->tmu_set_trip_hyst = exynos7_tmu_set_trip_hyst; in exynos_map_dt_data()
959 data->tmu_initialize = exynos7_tmu_initialize; in exynos_map_dt_data()
960 data->tmu_control = exynos7_tmu_control; in exynos_map_dt_data()
961 data->tmu_read = exynos7_tmu_read; in exynos_map_dt_data()
962 data->tmu_set_emulation = exynos4412_tmu_set_emulation; in exynos_map_dt_data()
963 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; in exynos_map_dt_data()
964 data->ntrip = 8; in exynos_map_dt_data()
965 data->gain = 9; in exynos_map_dt_data()
966 data->reference_voltage = 17; in exynos_map_dt_data()
967 data->efuse_value = 75; in exynos_map_dt_data()
968 data->min_efuse_value = 15; in exynos_map_dt_data()
969 data->max_efuse_value = 100; in exynos_map_dt_data()
972 dev_err(&pdev->dev, "Platform not supported\n"); in exynos_map_dt_data()
973 return -EINVAL; in exynos_map_dt_data()
976 data->cal_type = TYPE_ONE_POINT_TRIMMING; in exynos_map_dt_data()
979 * Check if the TMU shares some registers and then try to map the in exynos_map_dt_data()
982 if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO) in exynos_map_dt_data()
985 if (of_address_to_resource(pdev->dev.of_node, 1, &res)) { in exynos_map_dt_data()
986 dev_err(&pdev->dev, "failed to get Resource 1\n"); in exynos_map_dt_data()
987 return -ENODEV; in exynos_map_dt_data()
990 data->base_second = devm_ioremap(&pdev->dev, res.start, in exynos_map_dt_data()
992 if (!data->base_second) { in exynos_map_dt_data()
993 dev_err(&pdev->dev, "Failed to ioremap memory\n"); in exynos_map_dt_data()
994 return -ENOMEM; in exynos_map_dt_data()
1010 data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data), in exynos_tmu_probe()
1013 return -ENOMEM; in exynos_tmu_probe()
1016 mutex_init(&data->lock); in exynos_tmu_probe()
1023 data->regulator = devm_regulator_get_optional(&pdev->dev, "vtmu"); in exynos_tmu_probe()
1024 if (!IS_ERR(data->regulator)) { in exynos_tmu_probe()
1025 ret = regulator_enable(data->regulator); in exynos_tmu_probe()
1027 dev_err(&pdev->dev, "failed to enable vtmu\n"); in exynos_tmu_probe()
1031 if (PTR_ERR(data->regulator) == -EPROBE_DEFER) in exynos_tmu_probe()
1032 return -EPROBE_DEFER; in exynos_tmu_probe()
1033 dev_info(&pdev->dev, "Regulator node (vtmu) not found\n"); in exynos_tmu_probe()
1040 INIT_WORK(&data->irq_work, exynos_tmu_work); in exynos_tmu_probe()
1042 data->clk = devm_clk_get(&pdev->dev, "tmu_apbif"); in exynos_tmu_probe()
1043 if (IS_ERR(data->clk)) { in exynos_tmu_probe()
1044 dev_err(&pdev->dev, "Failed to get clock\n"); in exynos_tmu_probe()
1045 ret = PTR_ERR(data->clk); in exynos_tmu_probe()
1049 data->clk_sec = devm_clk_get(&pdev->dev, "tmu_triminfo_apbif"); in exynos_tmu_probe()
1050 if (IS_ERR(data->clk_sec)) { in exynos_tmu_probe()
1051 if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) { in exynos_tmu_probe()
1052 dev_err(&pdev->dev, "Failed to get triminfo clock\n"); in exynos_tmu_probe()
1053 ret = PTR_ERR(data->clk_sec); in exynos_tmu_probe()
1057 ret = clk_prepare(data->clk_sec); in exynos_tmu_probe()
1059 dev_err(&pdev->dev, "Failed to get clock\n"); in exynos_tmu_probe()
1064 ret = clk_prepare(data->clk); in exynos_tmu_probe()
1066 dev_err(&pdev->dev, "Failed to get clock\n"); in exynos_tmu_probe()
1070 switch (data->soc) { in exynos_tmu_probe()
1073 data->sclk = devm_clk_get(&pdev->dev, "tmu_sclk"); in exynos_tmu_probe()
1074 if (IS_ERR(data->sclk)) { in exynos_tmu_probe()
1075 dev_err(&pdev->dev, "Failed to get sclk\n"); in exynos_tmu_probe()
1076 ret = PTR_ERR(data->sclk); in exynos_tmu_probe()
1079 ret = clk_prepare_enable(data->sclk); in exynos_tmu_probe()
1081 dev_err(&pdev->dev, "Failed to enable sclk\n"); in exynos_tmu_probe()
1091 * data->tzd must be registered before calling exynos_tmu_initialize(), in exynos_tmu_probe()
1094 data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data, in exynos_tmu_probe()
1096 if (IS_ERR(data->tzd)) { in exynos_tmu_probe()
1097 ret = PTR_ERR(data->tzd); in exynos_tmu_probe()
1098 if (ret != -EPROBE_DEFER) in exynos_tmu_probe()
1099 dev_err(&pdev->dev, "Failed to register sensor: %d\n", in exynos_tmu_probe()
1106 dev_err(&pdev->dev, "Failed to initialize TMU\n"); in exynos_tmu_probe()
1110 ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq, in exynos_tmu_probe()
1111 IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data); in exynos_tmu_probe()
1113 dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq); in exynos_tmu_probe()
1121 thermal_zone_of_sensor_unregister(&pdev->dev, data->tzd); in exynos_tmu_probe()
1123 clk_disable_unprepare(data->sclk); in exynos_tmu_probe()
1125 clk_unprepare(data->clk); in exynos_tmu_probe()
1127 if (!IS_ERR(data->clk_sec)) in exynos_tmu_probe()
1128 clk_unprepare(data->clk_sec); in exynos_tmu_probe()
1130 if (!IS_ERR(data->regulator)) in exynos_tmu_probe()
1131 regulator_disable(data->regulator); in exynos_tmu_probe()
1139 struct thermal_zone_device *tzd = data->tzd; in exynos_tmu_remove()
1141 thermal_zone_of_sensor_unregister(&pdev->dev, tzd); in exynos_tmu_remove()
1144 clk_disable_unprepare(data->sclk); in exynos_tmu_remove()
1145 clk_unprepare(data->clk); in exynos_tmu_remove()
1146 if (!IS_ERR(data->clk_sec)) in exynos_tmu_remove()
1147 clk_unprepare(data->clk_sec); in exynos_tmu_remove()
1149 if (!IS_ERR(data->regulator)) in exynos_tmu_remove()
1150 regulator_disable(data->regulator); in exynos_tmu_remove()
1182 .name = "exynos-tmu",
1192 MODULE_DESCRIPTION("Exynos TMU Driver");
1195 MODULE_ALIAS("platform:exynos-tmu");