diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-28 22:48:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-28 22:48:26 -0500 |
commit | 2af78448fff61e13392daf4f770cfbcf9253316a (patch) | |
tree | 6c0494284dd1dd737d5f76ee19c553618e8d0e54 /drivers/thermal/exynos_thermal.c | |
parent | 5e04f4b4290e03deb91b074087ae8d7c169d947d (diff) | |
parent | f5b6d45f8cf688f51140fd21f1da3b90562762a9 (diff) |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management updates from Zhang Rui:
"Highlights:
- introduction of Dove thermal sensor driver.
- introduction of Kirkwood thermal sensor driver.
- introduction of intel_powerclamp thermal cooling device driver.
- add interrupt and DT support for rcar thermal driver.
- add thermal emulation support which allows platform thermal driver
to do software/hardware emulation for thermal issues."
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: (36 commits)
thermal: rcar: remove __devinitconst
thermal: return an error on failure to register thermal class
Thermal: rename thermal governor Kconfig option to avoid generic naming
thermal: exynos: Use the new thermal trend type for quick cooling action.
Thermal: exynos: Add support for temperature falling interrupt.
Thermal: Dove: Add Themal sensor support for Dove.
thermal: Add support for the thermal sensor on Kirkwood SoCs
thermal: rcar: add Device Tree support
thermal: rcar: remove machine_power_off() from rcar_thermal_notify()
thermal: rcar: add interrupt support
thermal: rcar: add read/write functions for common/priv data
thermal: rcar: multi channel support
thermal: rcar: use mutex lock instead of spin lock
thermal: rcar: enable CPCTL to use hardware TSC deciding
thermal: rcar: use parenthesis on macro
Thermal: fix a build warning when CONFIG_THERMAL_EMULATION cleared
Thermal: fix a wrong comment
thermal: sysfs: Add a new sysfs node emul_temp for thermal emulation
PM: intel_powerclamp: off by one in start_power_clamp()
thermal: exynos: Miscellaneous fixes to support falling threshold interrupt
...
Diffstat (limited to 'drivers/thermal/exynos_thermal.c')
-rw-r--r-- | drivers/thermal/exynos_thermal.c | 211 |
1 files changed, 164 insertions, 47 deletions
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c index bada1308318b..e04ebd8671ac 100644 --- a/drivers/thermal/exynos_thermal.c +++ b/drivers/thermal/exynos_thermal.c | |||
@@ -82,7 +82,7 @@ | |||
82 | 82 | ||
83 | #define EXYNOS_TRIMINFO_RELOAD 0x1 | 83 | #define EXYNOS_TRIMINFO_RELOAD 0x1 |
84 | #define EXYNOS_TMU_CLEAR_RISE_INT 0x111 | 84 | #define EXYNOS_TMU_CLEAR_RISE_INT 0x111 |
85 | #define EXYNOS_TMU_CLEAR_FALL_INT (0x111 << 16) | 85 | #define EXYNOS_TMU_CLEAR_FALL_INT (0x111 << 12) |
86 | #define EXYNOS_MUX_ADDR_VALUE 6 | 86 | #define EXYNOS_MUX_ADDR_VALUE 6 |
87 | #define EXYNOS_MUX_ADDR_SHIFT 20 | 87 | #define EXYNOS_MUX_ADDR_SHIFT 20 |
88 | #define EXYNOS_TMU_TRIP_MODE_SHIFT 13 | 88 | #define EXYNOS_TMU_TRIP_MODE_SHIFT 13 |
@@ -94,11 +94,20 @@ | |||
94 | #define SENSOR_NAME_LEN 16 | 94 | #define SENSOR_NAME_LEN 16 |
95 | #define MAX_TRIP_COUNT 8 | 95 | #define MAX_TRIP_COUNT 8 |
96 | #define MAX_COOLING_DEVICE 4 | 96 | #define MAX_COOLING_DEVICE 4 |
97 | #define MAX_THRESHOLD_LEVS 4 | ||
97 | 98 | ||
98 | #define ACTIVE_INTERVAL 500 | 99 | #define ACTIVE_INTERVAL 500 |
99 | #define IDLE_INTERVAL 10000 | 100 | #define IDLE_INTERVAL 10000 |
100 | #define MCELSIUS 1000 | 101 | #define MCELSIUS 1000 |
101 | 102 | ||
103 | #ifdef CONFIG_EXYNOS_THERMAL_EMUL | ||
104 | #define EXYNOS_EMUL_TIME 0x57F0 | ||
105 | #define EXYNOS_EMUL_TIME_SHIFT 16 | ||
106 | #define EXYNOS_EMUL_DATA_SHIFT 8 | ||
107 | #define EXYNOS_EMUL_DATA_MASK 0xFF | ||
108 | #define EXYNOS_EMUL_ENABLE 0x1 | ||
109 | #endif /* CONFIG_EXYNOS_THERMAL_EMUL */ | ||
110 | |||
102 | /* CPU Zone information */ | 111 | /* CPU Zone information */ |
103 | #define PANIC_ZONE 4 | 112 | #define PANIC_ZONE 4 |
104 | #define WARN_ZONE 3 | 113 | #define WARN_ZONE 3 |
@@ -125,6 +134,7 @@ struct exynos_tmu_data { | |||
125 | struct thermal_trip_point_conf { | 134 | struct thermal_trip_point_conf { |
126 | int trip_val[MAX_TRIP_COUNT]; | 135 | int trip_val[MAX_TRIP_COUNT]; |
127 | int trip_count; | 136 | int trip_count; |
137 | u8 trigger_falling; | ||
128 | }; | 138 | }; |
129 | 139 | ||
130 | struct thermal_cooling_conf { | 140 | struct thermal_cooling_conf { |
@@ -174,7 +184,8 @@ static int exynos_set_mode(struct thermal_zone_device *thermal, | |||
174 | 184 | ||
175 | mutex_lock(&th_zone->therm_dev->lock); | 185 | mutex_lock(&th_zone->therm_dev->lock); |
176 | 186 | ||
177 | if (mode == THERMAL_DEVICE_ENABLED) | 187 | if (mode == THERMAL_DEVICE_ENABLED && |
188 | !th_zone->sensor_conf->trip_data.trigger_falling) | ||
178 | th_zone->therm_dev->polling_delay = IDLE_INTERVAL; | 189 | th_zone->therm_dev->polling_delay = IDLE_INTERVAL; |
179 | else | 190 | else |
180 | th_zone->therm_dev->polling_delay = 0; | 191 | th_zone->therm_dev->polling_delay = 0; |
@@ -284,7 +295,7 @@ static int exynos_bind(struct thermal_zone_device *thermal, | |||
284 | case MONITOR_ZONE: | 295 | case MONITOR_ZONE: |
285 | case WARN_ZONE: | 296 | case WARN_ZONE: |
286 | if (thermal_zone_bind_cooling_device(thermal, i, cdev, | 297 | if (thermal_zone_bind_cooling_device(thermal, i, cdev, |
287 | level, level)) { | 298 | level, 0)) { |
288 | pr_err("error binding cdev inst %d\n", i); | 299 | pr_err("error binding cdev inst %d\n", i); |
289 | ret = -EINVAL; | 300 | ret = -EINVAL; |
290 | } | 301 | } |
@@ -362,10 +373,17 @@ static int exynos_get_temp(struct thermal_zone_device *thermal, | |||
362 | static int exynos_get_trend(struct thermal_zone_device *thermal, | 373 | static int exynos_get_trend(struct thermal_zone_device *thermal, |
363 | int trip, enum thermal_trend *trend) | 374 | int trip, enum thermal_trend *trend) |
364 | { | 375 | { |
365 | if (thermal->temperature >= trip) | 376 | int ret; |
366 | *trend = THERMAL_TREND_RAISING; | 377 | unsigned long trip_temp; |
378 | |||
379 | ret = exynos_get_trip_temp(thermal, trip, &trip_temp); | ||
380 | if (ret < 0) | ||
381 | return ret; | ||
382 | |||
383 | if (thermal->temperature >= trip_temp) | ||
384 | *trend = THERMAL_TREND_RAISE_FULL; | ||
367 | else | 385 | else |
368 | *trend = THERMAL_TREND_DROPPING; | 386 | *trend = THERMAL_TREND_DROP_FULL; |
369 | 387 | ||
370 | return 0; | 388 | return 0; |
371 | } | 389 | } |
@@ -413,7 +431,8 @@ static void exynos_report_trigger(void) | |||
413 | break; | 431 | break; |
414 | } | 432 | } |
415 | 433 | ||
416 | if (th_zone->mode == THERMAL_DEVICE_ENABLED) { | 434 | if (th_zone->mode == THERMAL_DEVICE_ENABLED && |
435 | !th_zone->sensor_conf->trip_data.trigger_falling) { | ||
417 | if (i > 0) | 436 | if (i > 0) |
418 | th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL; | 437 | th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL; |
419 | else | 438 | else |
@@ -452,7 +471,8 @@ static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) | |||
452 | 471 | ||
453 | th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name, | 472 | th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name, |
454 | EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0, | 473 | EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0, |
455 | IDLE_INTERVAL); | 474 | sensor_conf->trip_data.trigger_falling ? |
475 | 0 : IDLE_INTERVAL); | ||
456 | 476 | ||
457 | if (IS_ERR(th_zone->therm_dev)) { | 477 | if (IS_ERR(th_zone->therm_dev)) { |
458 | pr_err("Failed to register thermal zone device\n"); | 478 | pr_err("Failed to register thermal zone device\n"); |
@@ -559,8 +579,9 @@ static int exynos_tmu_initialize(struct platform_device *pdev) | |||
559 | { | 579 | { |
560 | struct exynos_tmu_data *data = platform_get_drvdata(pdev); | 580 | struct exynos_tmu_data *data = platform_get_drvdata(pdev); |
561 | struct exynos_tmu_platform_data *pdata = data->pdata; | 581 | struct exynos_tmu_platform_data *pdata = data->pdata; |
562 | unsigned int status, trim_info, rising_threshold; | 582 | unsigned int status, trim_info; |
563 | int ret = 0, threshold_code; | 583 | unsigned int rising_threshold = 0, falling_threshold = 0; |
584 | int ret = 0, threshold_code, i, trigger_levs = 0; | ||
564 | 585 | ||
565 | mutex_lock(&data->lock); | 586 | mutex_lock(&data->lock); |
566 | clk_enable(data->clk); | 587 | clk_enable(data->clk); |
@@ -585,6 +606,11 @@ static int exynos_tmu_initialize(struct platform_device *pdev) | |||
585 | (data->temp_error2 != 0)) | 606 | (data->temp_error2 != 0)) |
586 | data->temp_error1 = pdata->efuse_value; | 607 | data->temp_error1 = pdata->efuse_value; |
587 | 608 | ||
609 | /* Count trigger levels to be enabled */ | ||
610 | for (i = 0; i < MAX_THRESHOLD_LEVS; i++) | ||
611 | if (pdata->trigger_levels[i]) | ||
612 | trigger_levs++; | ||
613 | |||
588 | if (data->soc == SOC_ARCH_EXYNOS4210) { | 614 | if (data->soc == SOC_ARCH_EXYNOS4210) { |
589 | /* Write temperature code for threshold */ | 615 | /* Write temperature code for threshold */ |
590 | threshold_code = temp_to_code(data, pdata->threshold); | 616 | threshold_code = temp_to_code(data, pdata->threshold); |
@@ -594,44 +620,38 @@ static int exynos_tmu_initialize(struct platform_device *pdev) | |||
594 | } | 620 | } |
595 | writeb(threshold_code, | 621 | writeb(threshold_code, |
596 | data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); | 622 | data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); |
597 | 623 | for (i = 0; i < trigger_levs; i++) | |
598 | writeb(pdata->trigger_levels[0], | 624 | writeb(pdata->trigger_levels[i], |
599 | data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0); | 625 | data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4); |
600 | writeb(pdata->trigger_levels[1], | ||
601 | data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL1); | ||
602 | writeb(pdata->trigger_levels[2], | ||
603 | data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL2); | ||
604 | writeb(pdata->trigger_levels[3], | ||
605 | data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL3); | ||
606 | 626 | ||
607 | writel(EXYNOS4210_TMU_INTCLEAR_VAL, | 627 | writel(EXYNOS4210_TMU_INTCLEAR_VAL, |
608 | data->base + EXYNOS_TMU_REG_INTCLEAR); | 628 | data->base + EXYNOS_TMU_REG_INTCLEAR); |
609 | } else if (data->soc == SOC_ARCH_EXYNOS) { | 629 | } else if (data->soc == SOC_ARCH_EXYNOS) { |
610 | /* Write temperature code for threshold */ | 630 | /* Write temperature code for rising and falling threshold */ |
611 | threshold_code = temp_to_code(data, pdata->trigger_levels[0]); | 631 | for (i = 0; i < trigger_levs; i++) { |
612 | if (threshold_code < 0) { | 632 | threshold_code = temp_to_code(data, |
613 | ret = threshold_code; | 633 | pdata->trigger_levels[i]); |
614 | goto out; | 634 | if (threshold_code < 0) { |
615 | } | 635 | ret = threshold_code; |
616 | rising_threshold = threshold_code; | 636 | goto out; |
617 | threshold_code = temp_to_code(data, pdata->trigger_levels[1]); | 637 | } |
618 | if (threshold_code < 0) { | 638 | rising_threshold |= threshold_code << 8 * i; |
619 | ret = threshold_code; | 639 | if (pdata->threshold_falling) { |
620 | goto out; | 640 | threshold_code = temp_to_code(data, |
621 | } | 641 | pdata->trigger_levels[i] - |
622 | rising_threshold |= (threshold_code << 8); | 642 | pdata->threshold_falling); |
623 | threshold_code = temp_to_code(data, pdata->trigger_levels[2]); | 643 | if (threshold_code > 0) |
624 | if (threshold_code < 0) { | 644 | falling_threshold |= |
625 | ret = threshold_code; | 645 | threshold_code << 8 * i; |
626 | goto out; | 646 | } |
627 | } | 647 | } |
628 | rising_threshold |= (threshold_code << 16); | ||
629 | 648 | ||
630 | writel(rising_threshold, | 649 | writel(rising_threshold, |
631 | data->base + EXYNOS_THD_TEMP_RISE); | 650 | data->base + EXYNOS_THD_TEMP_RISE); |
632 | writel(0, data->base + EXYNOS_THD_TEMP_FALL); | 651 | writel(falling_threshold, |
652 | data->base + EXYNOS_THD_TEMP_FALL); | ||
633 | 653 | ||
634 | writel(EXYNOS_TMU_CLEAR_RISE_INT|EXYNOS_TMU_CLEAR_FALL_INT, | 654 | writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT, |
635 | data->base + EXYNOS_TMU_REG_INTCLEAR); | 655 | data->base + EXYNOS_TMU_REG_INTCLEAR); |
636 | } | 656 | } |
637 | out: | 657 | out: |
@@ -664,6 +684,8 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) | |||
664 | pdata->trigger_level2_en << 8 | | 684 | pdata->trigger_level2_en << 8 | |
665 | pdata->trigger_level1_en << 4 | | 685 | pdata->trigger_level1_en << 4 | |
666 | pdata->trigger_level0_en; | 686 | pdata->trigger_level0_en; |
687 | if (pdata->threshold_falling) | ||
688 | interrupt_en |= interrupt_en << 16; | ||
667 | } else { | 689 | } else { |
668 | con |= EXYNOS_TMU_CORE_OFF; | 690 | con |= EXYNOS_TMU_CORE_OFF; |
669 | interrupt_en = 0; /* Disable all interrupts */ | 691 | interrupt_en = 0; /* Disable all interrupts */ |
@@ -697,20 +719,19 @@ static void exynos_tmu_work(struct work_struct *work) | |||
697 | struct exynos_tmu_data *data = container_of(work, | 719 | struct exynos_tmu_data *data = container_of(work, |
698 | struct exynos_tmu_data, irq_work); | 720 | struct exynos_tmu_data, irq_work); |
699 | 721 | ||
722 | exynos_report_trigger(); | ||
700 | mutex_lock(&data->lock); | 723 | mutex_lock(&data->lock); |
701 | clk_enable(data->clk); | 724 | clk_enable(data->clk); |
702 | |||
703 | |||
704 | if (data->soc == SOC_ARCH_EXYNOS) | 725 | if (data->soc == SOC_ARCH_EXYNOS) |
705 | writel(EXYNOS_TMU_CLEAR_RISE_INT, | 726 | writel(EXYNOS_TMU_CLEAR_RISE_INT | |
727 | EXYNOS_TMU_CLEAR_FALL_INT, | ||
706 | data->base + EXYNOS_TMU_REG_INTCLEAR); | 728 | data->base + EXYNOS_TMU_REG_INTCLEAR); |
707 | else | 729 | else |
708 | writel(EXYNOS4210_TMU_INTCLEAR_VAL, | 730 | writel(EXYNOS4210_TMU_INTCLEAR_VAL, |
709 | data->base + EXYNOS_TMU_REG_INTCLEAR); | 731 | data->base + EXYNOS_TMU_REG_INTCLEAR); |
710 | |||
711 | clk_disable(data->clk); | 732 | clk_disable(data->clk); |
712 | mutex_unlock(&data->lock); | 733 | mutex_unlock(&data->lock); |
713 | exynos_report_trigger(); | 734 | |
714 | enable_irq(data->irq); | 735 | enable_irq(data->irq); |
715 | } | 736 | } |
716 | 737 | ||
@@ -759,6 +780,7 @@ static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = { | |||
759 | 780 | ||
760 | #if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412) | 781 | #if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412) |
761 | static struct exynos_tmu_platform_data const exynos_default_tmu_data = { | 782 | static struct exynos_tmu_platform_data const exynos_default_tmu_data = { |
783 | .threshold_falling = 10, | ||
762 | .trigger_levels[0] = 85, | 784 | .trigger_levels[0] = 85, |
763 | .trigger_levels[1] = 103, | 785 | .trigger_levels[1] = 103, |
764 | .trigger_levels[2] = 110, | 786 | .trigger_levels[2] = 110, |
@@ -800,8 +822,6 @@ static const struct of_device_id exynos_tmu_match[] = { | |||
800 | {}, | 822 | {}, |
801 | }; | 823 | }; |
802 | MODULE_DEVICE_TABLE(of, exynos_tmu_match); | 824 | MODULE_DEVICE_TABLE(of, exynos_tmu_match); |
803 | #else | ||
804 | #define exynos_tmu_match NULL | ||
805 | #endif | 825 | #endif |
806 | 826 | ||
807 | static struct platform_device_id exynos_tmu_driver_ids[] = { | 827 | static struct platform_device_id exynos_tmu_driver_ids[] = { |
@@ -832,6 +852,94 @@ static inline struct exynos_tmu_platform_data *exynos_get_driver_data( | |||
832 | return (struct exynos_tmu_platform_data *) | 852 | return (struct exynos_tmu_platform_data *) |
833 | platform_get_device_id(pdev)->driver_data; | 853 | platform_get_device_id(pdev)->driver_data; |
834 | } | 854 | } |
855 | |||
856 | #ifdef CONFIG_EXYNOS_THERMAL_EMUL | ||
857 | static ssize_t exynos_tmu_emulation_show(struct device *dev, | ||
858 | struct device_attribute *attr, | ||
859 | char *buf) | ||
860 | { | ||
861 | struct platform_device *pdev = container_of(dev, | ||
862 | struct platform_device, dev); | ||
863 | struct exynos_tmu_data *data = platform_get_drvdata(pdev); | ||
864 | unsigned int reg; | ||
865 | u8 temp_code; | ||
866 | int temp = 0; | ||
867 | |||
868 | if (data->soc == SOC_ARCH_EXYNOS4210) | ||
869 | goto out; | ||
870 | |||
871 | mutex_lock(&data->lock); | ||
872 | clk_enable(data->clk); | ||
873 | reg = readl(data->base + EXYNOS_EMUL_CON); | ||
874 | clk_disable(data->clk); | ||
875 | mutex_unlock(&data->lock); | ||
876 | |||
877 | if (reg & EXYNOS_EMUL_ENABLE) { | ||
878 | reg >>= EXYNOS_EMUL_DATA_SHIFT; | ||
879 | temp_code = reg & EXYNOS_EMUL_DATA_MASK; | ||
880 | temp = code_to_temp(data, temp_code); | ||
881 | } | ||
882 | out: | ||
883 | return sprintf(buf, "%d\n", temp * MCELSIUS); | ||
884 | } | ||
885 | |||
886 | static ssize_t exynos_tmu_emulation_store(struct device *dev, | ||
887 | struct device_attribute *attr, | ||
888 | const char *buf, size_t count) | ||
889 | { | ||
890 | struct platform_device *pdev = container_of(dev, | ||
891 | struct platform_device, dev); | ||
892 | struct exynos_tmu_data *data = platform_get_drvdata(pdev); | ||
893 | unsigned int reg; | ||
894 | int temp; | ||
895 | |||
896 | if (data->soc == SOC_ARCH_EXYNOS4210) | ||
897 | goto out; | ||
898 | |||
899 | if (!sscanf(buf, "%d\n", &temp) || temp < 0) | ||
900 | return -EINVAL; | ||
901 | |||
902 | mutex_lock(&data->lock); | ||
903 | clk_enable(data->clk); | ||
904 | |||
905 | reg = readl(data->base + EXYNOS_EMUL_CON); | ||
906 | |||
907 | if (temp) { | ||
908 | /* Both CELSIUS and MCELSIUS type are available for input */ | ||
909 | if (temp > MCELSIUS) | ||
910 | temp /= MCELSIUS; | ||
911 | |||
912 | reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) | | ||
913 | (temp_to_code(data, (temp / MCELSIUS)) | ||
914 | << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE; | ||
915 | } else { | ||
916 | reg &= ~EXYNOS_EMUL_ENABLE; | ||
917 | } | ||
918 | |||
919 | writel(reg, data->base + EXYNOS_EMUL_CON); | ||
920 | |||
921 | clk_disable(data->clk); | ||
922 | mutex_unlock(&data->lock); | ||
923 | |||
924 | out: | ||
925 | return count; | ||
926 | } | ||
927 | |||
928 | static DEVICE_ATTR(emulation, 0644, exynos_tmu_emulation_show, | ||
929 | exynos_tmu_emulation_store); | ||
930 | static int create_emulation_sysfs(struct device *dev) | ||
931 | { | ||
932 | return device_create_file(dev, &dev_attr_emulation); | ||
933 | } | ||
934 | static void remove_emulation_sysfs(struct device *dev) | ||
935 | { | ||
936 | device_remove_file(dev, &dev_attr_emulation); | ||
937 | } | ||
938 | #else | ||
939 | static inline int create_emulation_sysfs(struct device *dev) { return 0; } | ||
940 | static inline void remove_emulation_sysfs(struct device *dev) {} | ||
941 | #endif | ||
942 | |||
835 | static int exynos_tmu_probe(struct platform_device *pdev) | 943 | static int exynos_tmu_probe(struct platform_device *pdev) |
836 | { | 944 | { |
837 | struct exynos_tmu_data *data; | 945 | struct exynos_tmu_data *data; |
@@ -914,6 +1022,8 @@ static int exynos_tmu_probe(struct platform_device *pdev) | |||
914 | exynos_sensor_conf.trip_data.trip_val[i] = | 1022 | exynos_sensor_conf.trip_data.trip_val[i] = |
915 | pdata->threshold + pdata->trigger_levels[i]; | 1023 | pdata->threshold + pdata->trigger_levels[i]; |
916 | 1024 | ||
1025 | exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling; | ||
1026 | |||
917 | exynos_sensor_conf.cooling_data.freq_clip_count = | 1027 | exynos_sensor_conf.cooling_data.freq_clip_count = |
918 | pdata->freq_tab_count; | 1028 | pdata->freq_tab_count; |
919 | for (i = 0; i < pdata->freq_tab_count; i++) { | 1029 | for (i = 0; i < pdata->freq_tab_count; i++) { |
@@ -928,6 +1038,11 @@ static int exynos_tmu_probe(struct platform_device *pdev) | |||
928 | dev_err(&pdev->dev, "Failed to register thermal interface\n"); | 1038 | dev_err(&pdev->dev, "Failed to register thermal interface\n"); |
929 | goto err_clk; | 1039 | goto err_clk; |
930 | } | 1040 | } |
1041 | |||
1042 | ret = create_emulation_sysfs(&pdev->dev); | ||
1043 | if (ret) | ||
1044 | dev_err(&pdev->dev, "Failed to create emulation mode sysfs node\n"); | ||
1045 | |||
931 | return 0; | 1046 | return 0; |
932 | err_clk: | 1047 | err_clk: |
933 | platform_set_drvdata(pdev, NULL); | 1048 | platform_set_drvdata(pdev, NULL); |
@@ -939,6 +1054,8 @@ static int exynos_tmu_remove(struct platform_device *pdev) | |||
939 | { | 1054 | { |
940 | struct exynos_tmu_data *data = platform_get_drvdata(pdev); | 1055 | struct exynos_tmu_data *data = platform_get_drvdata(pdev); |
941 | 1056 | ||
1057 | remove_emulation_sysfs(&pdev->dev); | ||
1058 | |||
942 | exynos_tmu_control(pdev, false); | 1059 | exynos_tmu_control(pdev, false); |
943 | 1060 | ||
944 | exynos_unregister_thermal(); | 1061 | exynos_unregister_thermal(); |
@@ -980,7 +1097,7 @@ static struct platform_driver exynos_tmu_driver = { | |||
980 | .name = "exynos-tmu", | 1097 | .name = "exynos-tmu", |
981 | .owner = THIS_MODULE, | 1098 | .owner = THIS_MODULE, |
982 | .pm = EXYNOS_TMU_PM, | 1099 | .pm = EXYNOS_TMU_PM, |
983 | .of_match_table = exynos_tmu_match, | 1100 | .of_match_table = of_match_ptr(exynos_tmu_match), |
984 | }, | 1101 | }, |
985 | .probe = exynos_tmu_probe, | 1102 | .probe = exynos_tmu_probe, |
986 | .remove = exynos_tmu_remove, | 1103 | .remove = exynos_tmu_remove, |