exynos5422-dmc.c (d51e6a69f4e9e81cf75bbfdccce60d47e31ad901) exynos5422-dmc.c (bbf918863e183d66adf00ca1b24fb641149a0d3d)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
4 * Author: Lukasz Luba <l.luba@partner.samsung.com>
5 */
6
7#include <linux/clk.h>
8#include <linux/devfreq.h>
9#include <linux/devfreq-event.h>
10#include <linux/device.h>
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
4 * Author: Lukasz Luba <l.luba@partner.samsung.com>
5 */
6
7#include <linux/clk.h>
8#include <linux/devfreq.h>
9#include <linux/devfreq-event.h>
10#include <linux/device.h>
11#include <linux/interrupt.h>
11#include <linux/io.h>
12#include <linux/mfd/syscon.h>
13#include <linux/module.h>
14#include <linux/of_device.h>
15#include <linux/pm_opp.h>
16#include <linux/platform_device.h>
17#include <linux/regmap.h>
18#include <linux/regulator/consumer.h>

--- 11 unchanged lines hidden (view full) ---

30#define CDREX_PAUSE (0x2091c)
31#define CDREX_LPDDR3PHY_CON3 (0x20a20)
32#define CDREX_LPDDR3PHY_CLKM_SRC (0x20700)
33#define EXYNOS5_TIMING_SET_SWI BIT(28)
34#define USE_MX_MSPLL_TIMINGS (1)
35#define USE_BPLL_TIMINGS (0)
36#define EXYNOS5_AREF_NORMAL (0x2e)
37
12#include <linux/io.h>
13#include <linux/mfd/syscon.h>
14#include <linux/module.h>
15#include <linux/of_device.h>
16#include <linux/pm_opp.h>
17#include <linux/platform_device.h>
18#include <linux/regmap.h>
19#include <linux/regulator/consumer.h>

--- 11 unchanged lines hidden (view full) ---

31#define CDREX_PAUSE (0x2091c)
32#define CDREX_LPDDR3PHY_CON3 (0x20a20)
33#define CDREX_LPDDR3PHY_CLKM_SRC (0x20700)
34#define EXYNOS5_TIMING_SET_SWI BIT(28)
35#define USE_MX_MSPLL_TIMINGS (1)
36#define USE_BPLL_TIMINGS (0)
37#define EXYNOS5_AREF_NORMAL (0x2e)
38
39#define DREX_PPCCLKCON (0x0130)
40#define DREX_PEREV2CONFIG (0x013c)
41#define DREX_PMNC_PPC (0xE000)
42#define DREX_CNTENS_PPC (0xE010)
43#define DREX_CNTENC_PPC (0xE020)
44#define DREX_INTENS_PPC (0xE030)
45#define DREX_INTENC_PPC (0xE040)
46#define DREX_FLAG_PPC (0xE050)
47#define DREX_PMCNT2_PPC (0xE130)
48
49/*
50 * A value for register DREX_PMNC_PPC which should be written to reset
51 * the cycle counter CCNT (a reference wall clock). It sets zero to the
52 * CCNT counter.
53 */
54#define CC_RESET BIT(2)
55
56/*
57 * A value for register DREX_PMNC_PPC which does the reset of all performance
58 * counters to zero.
59 */
60#define PPC_COUNTER_RESET BIT(1)
61
62/*
63 * Enables all configured counters (including cycle counter). The value should
64 * be written to the register DREX_PMNC_PPC.
65 */
66#define PPC_ENABLE BIT(0)
67
68/* A value for register DREX_PPCCLKCON which enables performance events clock.
69 * Must be written before first access to the performance counters register
70 * set, otherwise it could crash.
71 */
72#define PEREV_CLK_EN BIT(0)
73
74/*
75 * Values which are used to enable counters, interrupts or configure flags of
76 * the performance counters. They configure counter 2 and cycle counter.
77 */
78#define PERF_CNT2 BIT(2)
79#define PERF_CCNT BIT(31)
80
81/*
82 * Performance event types which are used for setting the preferred event
83 * to track in the counters.
84 * There is a set of different types, the values are from range 0 to 0x6f.
85 * These settings should be written to the configuration register which manages
86 * the type of the event (register DREX_PEREV2CONFIG).
87 */
88#define READ_TRANSFER_CH0 (0x6d)
89#define READ_TRANSFER_CH1 (0x6f)
90
91#define PERF_COUNTER_START_VALUE 0xff000000
92#define PERF_EVENT_UP_DOWN_THRESHOLD 900000000ULL
93
38/**
39 * struct dmc_opp_table - Operating level desciption
40 *
41 * Covers frequency and voltage settings of the DMC operating mode.
42 */
43struct dmc_opp_table {
44 u32 freq_hz;
45 u32 volt_uv;

--- 34 unchanged lines hidden (view full) ---

80 struct clk *mout_spll;
81 struct clk *mout_bpll;
82 struct clk *mout_mclk_cdrex;
83 struct clk *mout_mx_mspll_ccore;
84 struct clk *mx_mspll_ccore_phy;
85 struct clk *mout_mx_mspll_ccore_phy;
86 struct devfreq_event_dev **counter;
87 int num_counters;
94/**
95 * struct dmc_opp_table - Operating level desciption
96 *
97 * Covers frequency and voltage settings of the DMC operating mode.
98 */
99struct dmc_opp_table {
100 u32 freq_hz;
101 u32 volt_uv;

--- 34 unchanged lines hidden (view full) ---

136 struct clk *mout_spll;
137 struct clk *mout_bpll;
138 struct clk *mout_mclk_cdrex;
139 struct clk *mout_mx_mspll_ccore;
140 struct clk *mx_mspll_ccore_phy;
141 struct clk *mout_mx_mspll_ccore_phy;
142 struct devfreq_event_dev **counter;
143 int num_counters;
144 u64 last_overflow_ts[2];
145 unsigned long load;
146 unsigned long total;
147 bool in_irq_mode;
88};
89
90#define TIMING_FIELD(t_name, t_bit_beg, t_bit_end) \
91 { .name = t_name, .bit_beg = t_bit_beg, .bit_end = t_bit_end }
92
93#define TIMING_VAL2REG(timing, t_val) \
94({ \
95 u32 __val; \

--- 553 unchanged lines hidden (view full) ---

649 }
650
651 *total_count = total;
652
653 return 0;
654}
655
656/**
148};
149
150#define TIMING_FIELD(t_name, t_bit_beg, t_bit_end) \
151 { .name = t_name, .bit_beg = t_bit_beg, .bit_end = t_bit_end }
152
153#define TIMING_VAL2REG(timing, t_val) \
154({ \
155 u32 __val; \

--- 553 unchanged lines hidden (view full) ---

709 }
710
711 *total_count = total;
712
713 return 0;
714}
715
716/**
717 * exynos5_dmc_start_perf_events() - Setup and start performance event counters
718 * @dmc: device for which the counters are going to be checked
719 * @beg_value: initial value for the counter
720 *
721 * Function which enables needed counters, interrupts and sets initial values
722 * then starts the counters.
723 */
724static void exynos5_dmc_start_perf_events(struct exynos5_dmc *dmc,
725 u32 beg_value)
726{
727 /* Enable interrupts for counter 2 */
728 writel(PERF_CNT2, dmc->base_drexi0 + DREX_INTENS_PPC);
729 writel(PERF_CNT2, dmc->base_drexi1 + DREX_INTENS_PPC);
730
731 /* Enable counter 2 and CCNT */
732 writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_CNTENS_PPC);
733 writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_CNTENS_PPC);
734
735 /* Clear overflow flag for all counters */
736 writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_FLAG_PPC);
737 writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_FLAG_PPC);
738
739 /* Reset all counters */
740 writel(CC_RESET | PPC_COUNTER_RESET, dmc->base_drexi0 + DREX_PMNC_PPC);
741 writel(CC_RESET | PPC_COUNTER_RESET, dmc->base_drexi1 + DREX_PMNC_PPC);
742
743 /*
744 * Set start value for the counters, the number of samples that
745 * will be gathered is calculated as: 0xffffffff - beg_value
746 */
747 writel(beg_value, dmc->base_drexi0 + DREX_PMCNT2_PPC);
748 writel(beg_value, dmc->base_drexi1 + DREX_PMCNT2_PPC);
749
750 /* Start all counters */
751 writel(PPC_ENABLE, dmc->base_drexi0 + DREX_PMNC_PPC);
752 writel(PPC_ENABLE, dmc->base_drexi1 + DREX_PMNC_PPC);
753}
754
755/**
756 * exynos5_dmc_perf_events_calc() - Calculate utilization
757 * @dmc: device for which the counters are going to be checked
758 * @diff_ts: time between last interrupt and current one
759 *
760 * Function which calculates needed utilization for the devfreq governor.
761 * It prepares values for 'busy_time' and 'total_time' based on elapsed time
762 * between interrupts, which approximates utilization.
763 */
764static void exynos5_dmc_perf_events_calc(struct exynos5_dmc *dmc, u64 diff_ts)
765{
766 /*
767 * This is a simple algorithm for managing traffic on DMC.
768 * When there is almost no load the counters overflow every 4s,
769 * no mater the DMC frequency.
770 * The high load might be approximated using linear function.
771 * Knowing that, simple calculation can provide 'busy_time' and
772 * 'total_time' to the devfreq governor which picks up target
773 * frequency.
774 * We want a fast ramp up and slow decay in frequency change function.
775 */
776 if (diff_ts < PERF_EVENT_UP_DOWN_THRESHOLD) {
777 /*
778 * Set higher utilization for the simple_ondemand governor.
779 * The governor should increase the frequency of the DMC.
780 */
781 dmc->load = 70;
782 dmc->total = 100;
783 } else {
784 /*
785 * Set low utilization for the simple_ondemand governor.
786 * The governor should decrease the frequency of the DMC.
787 */
788 dmc->load = 35;
789 dmc->total = 100;
790 }
791
792 dev_dbg(dmc->dev, "diff_ts=%llu\n", diff_ts);
793}
794
795/**
796 * exynos5_dmc_perf_events_check() - Checks the status of the counters
797 * @dmc: device for which the counters are going to be checked
798 *
799 * Function which is called from threaded IRQ to check the counters state
800 * and to call approximation for the needed utilization.
801 */
802static void exynos5_dmc_perf_events_check(struct exynos5_dmc *dmc)
803{
804 u32 val;
805 u64 diff_ts, ts;
806
807 ts = ktime_get_ns();
808
809 /* Stop all counters */
810 writel(0, dmc->base_drexi0 + DREX_PMNC_PPC);
811 writel(0, dmc->base_drexi1 + DREX_PMNC_PPC);
812
813 /* Check the source in interrupt flag registers (which channel) */
814 val = readl(dmc->base_drexi0 + DREX_FLAG_PPC);
815 if (val) {
816 diff_ts = ts - dmc->last_overflow_ts[0];
817 dmc->last_overflow_ts[0] = ts;
818 dev_dbg(dmc->dev, "drex0 0xE050 val= 0x%08x\n", val);
819 } else {
820 val = readl(dmc->base_drexi1 + DREX_FLAG_PPC);
821 diff_ts = ts - dmc->last_overflow_ts[1];
822 dmc->last_overflow_ts[1] = ts;
823 dev_dbg(dmc->dev, "drex1 0xE050 val= 0x%08x\n", val);
824 }
825
826 exynos5_dmc_perf_events_calc(dmc, diff_ts);
827
828 exynos5_dmc_start_perf_events(dmc, PERF_COUNTER_START_VALUE);
829}
830
831/**
832 * exynos5_dmc_enable_perf_events() - Enable performance events
833 * @dmc: device for which the counters are going to be checked
834 *
835 * Function which is setup needed environment and enables counters.
836 */
837static void exynos5_dmc_enable_perf_events(struct exynos5_dmc *dmc)
838{
839 u64 ts;
840
841 /* Enable Performance Event Clock */
842 writel(PEREV_CLK_EN, dmc->base_drexi0 + DREX_PPCCLKCON);
843 writel(PEREV_CLK_EN, dmc->base_drexi1 + DREX_PPCCLKCON);
844
845 /* Select read transfers as performance event2 */
846 writel(READ_TRANSFER_CH0, dmc->base_drexi0 + DREX_PEREV2CONFIG);
847 writel(READ_TRANSFER_CH1, dmc->base_drexi1 + DREX_PEREV2CONFIG);
848
849 ts = ktime_get_ns();
850 dmc->last_overflow_ts[0] = ts;
851 dmc->last_overflow_ts[1] = ts;
852
853 /* Devfreq shouldn't be faster than initialization, play safe though. */
854 dmc->load = 99;
855 dmc->total = 100;
856}
857
858/**
859 * exynos5_dmc_disable_perf_events() - Disable performance events
860 * @dmc: device for which the counters are going to be checked
861 *
862 * Function which stops, disables performance event counters and interrupts.
863 */
864static void exynos5_dmc_disable_perf_events(struct exynos5_dmc *dmc)
865{
866 /* Stop all counters */
867 writel(0, dmc->base_drexi0 + DREX_PMNC_PPC);
868 writel(0, dmc->base_drexi1 + DREX_PMNC_PPC);
869
870 /* Disable interrupts for counter 2 */
871 writel(PERF_CNT2, dmc->base_drexi0 + DREX_INTENC_PPC);
872 writel(PERF_CNT2, dmc->base_drexi1 + DREX_INTENC_PPC);
873
874 /* Disable counter 2 and CCNT */
875 writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_CNTENC_PPC);
876 writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_CNTENC_PPC);
877
878 /* Clear overflow flag for all counters */
879 writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_FLAG_PPC);
880 writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_FLAG_PPC);
881}
882
883/**
657 * exynos5_dmc_get_status() - Read current DMC performance statistics.
658 * @dev: device for which the statistics are requested
659 * @stat: structure which has statistic fields
660 *
661 * Function reads the DMC performance counters and calculates 'busy_time'
662 * and 'total_time'. To protect from overflow, the values are shifted right
663 * by 10. After read out the counters are setup to count again.
664 */
665static int exynos5_dmc_get_status(struct device *dev,
666 struct devfreq_dev_status *stat)
667{
668 struct exynos5_dmc *dmc = dev_get_drvdata(dev);
669 unsigned long load, total;
670 int ret;
671
884 * exynos5_dmc_get_status() - Read current DMC performance statistics.
885 * @dev: device for which the statistics are requested
886 * @stat: structure which has statistic fields
887 *
888 * Function reads the DMC performance counters and calculates 'busy_time'
889 * and 'total_time'. To protect from overflow, the values are shifted right
890 * by 10. After read out the counters are setup to count again.
891 */
892static int exynos5_dmc_get_status(struct device *dev,
893 struct devfreq_dev_status *stat)
894{
895 struct exynos5_dmc *dmc = dev_get_drvdata(dev);
896 unsigned long load, total;
897 int ret;
898
672 ret = exynos5_counters_get(dmc, &load, &total);
673 if (ret < 0)
674 return -EINVAL;
899 if (dmc->in_irq_mode) {
900 stat->current_frequency = dmc->curr_rate;
901 stat->busy_time = dmc->load;
902 stat->total_time = dmc->total;
903 } else {
904 ret = exynos5_counters_get(dmc, &load, &total);
905 if (ret < 0)
906 return -EINVAL;
675
907
676 /* To protect from overflow in calculation ratios, divide by 1024 */
677 stat->busy_time = load >> 10;
678 stat->total_time = total >> 10;
908 /* To protect from overflow, divide by 1024 */
909 stat->busy_time = load >> 10;
910 stat->total_time = total >> 10;
679
911
680 ret = exynos5_counters_set_event(dmc);
681 if (ret < 0) {
682 dev_err(dev, "could not set event counter\n");
683 return ret;
912 ret = exynos5_counters_set_event(dmc);
913 if (ret < 0) {
914 dev_err(dev, "could not set event counter\n");
915 return ret;
916 }
684 }
685
686 return 0;
687}
688
689/**
690 * exynos5_dmc_get_cur_freq() - Function returns current DMC frequency
691 * @dev: device for which the framework checks operating frequency

--- 15 unchanged lines hidden (view full) ---

707}
708
709/**
710 * exynos5_dmc_df_profile - Devfreq governor's profile structure
711 *
712 * It provides to the devfreq framework needed functions and polling period.
713 */
714static struct devfreq_dev_profile exynos5_dmc_df_profile = {
917 }
918
919 return 0;
920}
921
922/**
923 * exynos5_dmc_get_cur_freq() - Function returns current DMC frequency
924 * @dev: device for which the framework checks operating frequency

--- 15 unchanged lines hidden (view full) ---

940}
941
942/**
943 * exynos5_dmc_df_profile - Devfreq governor's profile structure
944 *
945 * It provides to the devfreq framework needed functions and polling period.
946 */
947static struct devfreq_dev_profile exynos5_dmc_df_profile = {
715 .polling_ms = 500,
716 .target = exynos5_dmc_target,
717 .get_dev_status = exynos5_dmc_get_status,
718 .get_cur_freq = exynos5_dmc_get_cur_freq,
719};
720
721/**
722 * exynos5_dmc_align_initial_frequency() - Align initial frequency value
723 * @dmc: device for which the frequency is going to be set

--- 379 unchanged lines hidden (view full) ---

1103 return ret;
1104
1105 val |= 1UL;
1106 regmap_write(dmc->clk_regmap, CDREX_PAUSE, val);
1107
1108 return 0;
1109}
1110
948 .target = exynos5_dmc_target,
949 .get_dev_status = exynos5_dmc_get_status,
950 .get_cur_freq = exynos5_dmc_get_cur_freq,
951};
952
953/**
954 * exynos5_dmc_align_initial_frequency() - Align initial frequency value
955 * @dmc: device for which the frequency is going to be set

--- 379 unchanged lines hidden (view full) ---

1335 return ret;
1336
1337 val |= 1UL;
1338 regmap_write(dmc->clk_regmap, CDREX_PAUSE, val);
1339
1340 return 0;
1341}
1342
1343static irqreturn_t dmc_irq_thread(int irq, void *priv)
1344{
1345 int res;
1346 struct exynos5_dmc *dmc = priv;
1347
1348 mutex_lock(&dmc->df->lock);
1349
1350 exynos5_dmc_perf_events_check(dmc);
1351
1352 res = update_devfreq(dmc->df);
1353 if (res)
1354 dev_warn(dmc->dev, "devfreq failed with %d\n", res);
1355
1356 mutex_unlock(&dmc->df->lock);
1357
1358 return IRQ_HANDLED;
1359}
1360
1111/**
1112 * exynos5_dmc_probe() - Probe function for the DMC driver
1113 * @pdev: platform device for which the driver is going to be initialized
1114 *
1115 * Initialize basic components: clocks, regulators, performance counters, etc.
1116 * Read out product version and based on the information setup
1117 * internal structures for the controller (frequency and voltage) and for DRAM
1118 * memory parameters: timings for each operating frequency.
1119 * Register new devfreq device for controlling DVFS of the DMC.
1120 */
1121static int exynos5_dmc_probe(struct platform_device *pdev)
1122{
1123 int ret = 0;
1124 struct device *dev = &pdev->dev;
1125 struct device_node *np = dev->of_node;
1126 struct exynos5_dmc *dmc;
1127 struct resource *res;
1361/**
1362 * exynos5_dmc_probe() - Probe function for the DMC driver
1363 * @pdev: platform device for which the driver is going to be initialized
1364 *
1365 * Initialize basic components: clocks, regulators, performance counters, etc.
1366 * Read out product version and based on the information setup
1367 * internal structures for the controller (frequency and voltage) and for DRAM
1368 * memory parameters: timings for each operating frequency.
1369 * Register new devfreq device for controlling DVFS of the DMC.
1370 */
1371static int exynos5_dmc_probe(struct platform_device *pdev)
1372{
1373 int ret = 0;
1374 struct device *dev = &pdev->dev;
1375 struct device_node *np = dev->of_node;
1376 struct exynos5_dmc *dmc;
1377 struct resource *res;
1378 int irq[2];
1128
1129 dmc = devm_kzalloc(dev, sizeof(*dmc), GFP_KERNEL);
1130 if (!dmc)
1131 return -ENOMEM;
1132
1133 mutex_init(&dmc->lock);
1134
1135 dmc->dev = dev;

--- 31 unchanged lines hidden (view full) ---

1167 return ret;
1168
1169 ret = of_get_dram_timings(dmc);
1170 if (ret) {
1171 dev_warn(dev, "couldn't initialize timings settings\n");
1172 goto remove_clocks;
1173 }
1174
1379
1380 dmc = devm_kzalloc(dev, sizeof(*dmc), GFP_KERNEL);
1381 if (!dmc)
1382 return -ENOMEM;
1383
1384 mutex_init(&dmc->lock);
1385
1386 dmc->dev = dev;

--- 31 unchanged lines hidden (view full) ---

1418 return ret;
1419
1420 ret = of_get_dram_timings(dmc);
1421 if (ret) {
1422 dev_warn(dev, "couldn't initialize timings settings\n");
1423 goto remove_clocks;
1424 }
1425
1175 ret = exynos5_performance_counters_init(dmc);
1426 ret = exynos5_dmc_set_pause_on_switching(dmc);
1176 if (ret) {
1427 if (ret) {
1177 dev_warn(dev, "couldn't probe performance counters\n");
1428 dev_warn(dev, "couldn't get access to PAUSE register\n");
1178 goto remove_clocks;
1179 }
1180
1429 goto remove_clocks;
1430 }
1431
1181 ret = exynos5_dmc_set_pause_on_switching(dmc);
1182 if (ret) {
1183 dev_warn(dev, "couldn't get access to PAUSE register\n");
1184 goto err_devfreq_add;
1432 /* There is two modes in which the driver works: polling or IRQ */
1433 irq[0] = platform_get_irq_byname(pdev, "drex_0");
1434 irq[1] = platform_get_irq_byname(pdev, "drex_1");
1435 if (irq[0] > 0 && irq[1] > 0) {
1436 ret = devm_request_threaded_irq(dev, irq[0], NULL,
1437 dmc_irq_thread, IRQF_ONESHOT,
1438 dev_name(dev), dmc);
1439 if (ret) {
1440 dev_err(dev, "couldn't grab IRQ\n");
1441 goto remove_clocks;
1442 }
1443
1444 ret = devm_request_threaded_irq(dev, irq[1], NULL,
1445 dmc_irq_thread, IRQF_ONESHOT,
1446 dev_name(dev), dmc);
1447 if (ret) {
1448 dev_err(dev, "couldn't grab IRQ\n");
1449 goto remove_clocks;
1450 }
1451
1452 /*
1453 * Setup default thresholds for the devfreq governor.
1454 * The values are chosen based on experiments.
1455 */
1456 dmc->gov_data.upthreshold = 55;
1457 dmc->gov_data.downdifferential = 5;
1458
1459 exynos5_dmc_enable_perf_events(dmc);
1460
1461 dmc->in_irq_mode = 1;
1462 } else {
1463 ret = exynos5_performance_counters_init(dmc);
1464 if (ret) {
1465 dev_warn(dev, "couldn't probe performance counters\n");
1466 goto remove_clocks;
1467 }
1468
1469 /*
1470 * Setup default thresholds for the devfreq governor.
1471 * The values are chosen based on experiments.
1472 */
1473 dmc->gov_data.upthreshold = 30;
1474 dmc->gov_data.downdifferential = 5;
1475
1476 exynos5_dmc_df_profile.polling_ms = 500;
1185 }
1186
1477 }
1478
1187 /*
1188 * Setup default thresholds for the devfreq governor.
1189 * The values are chosen based on experiments.
1190 */
1191 dmc->gov_data.upthreshold = 30;
1192 dmc->gov_data.downdifferential = 5;
1193
1194 dmc->df = devm_devfreq_add_device(dev, &exynos5_dmc_df_profile,
1195 DEVFREQ_GOV_SIMPLE_ONDEMAND,
1196 &dmc->gov_data);
1197
1198 if (IS_ERR(dmc->df)) {
1199 ret = PTR_ERR(dmc->df);
1200 goto err_devfreq_add;
1201 }
1202
1479
1480 dmc->df = devm_devfreq_add_device(dev, &exynos5_dmc_df_profile,
1481 DEVFREQ_GOV_SIMPLE_ONDEMAND,
1482 &dmc->gov_data);
1483
1484 if (IS_ERR(dmc->df)) {
1485 ret = PTR_ERR(dmc->df);
1486 goto err_devfreq_add;
1487 }
1488
1489 if (dmc->in_irq_mode)
1490 exynos5_dmc_start_perf_events(dmc, PERF_COUNTER_START_VALUE);
1491
1203 dev_info(dev, "DMC initialized\n");
1204
1205 return 0;
1206
1207err_devfreq_add:
1492 dev_info(dev, "DMC initialized\n");
1493
1494 return 0;
1495
1496err_devfreq_add:
1208 exynos5_counters_disable_edev(dmc);
1497 if (dmc->in_irq_mode)
1498 exynos5_dmc_disable_perf_events(dmc);
1499 else
1500 exynos5_counters_disable_edev(dmc);
1209remove_clocks:
1210 clk_disable_unprepare(dmc->mout_bpll);
1211 clk_disable_unprepare(dmc->fout_bpll);
1212
1213 return ret;
1214}
1215
1216/**
1217 * exynos5_dmc_remove() - Remove function for the platform device
1218 * @pdev: platform device which is going to be removed
1219 *
1220 * The function relies on 'devm' framework function which automatically
1221 * clean the device's resources. It just calls explicitly disable function for
1222 * the performance counters.
1223 */
1224static int exynos5_dmc_remove(struct platform_device *pdev)
1225{
1226 struct exynos5_dmc *dmc = dev_get_drvdata(&pdev->dev);
1227
1501remove_clocks:
1502 clk_disable_unprepare(dmc->mout_bpll);
1503 clk_disable_unprepare(dmc->fout_bpll);
1504
1505 return ret;
1506}
1507
1508/**
1509 * exynos5_dmc_remove() - Remove function for the platform device
1510 * @pdev: platform device which is going to be removed
1511 *
1512 * The function relies on 'devm' framework function which automatically
1513 * clean the device's resources. It just calls explicitly disable function for
1514 * the performance counters.
1515 */
1516static int exynos5_dmc_remove(struct platform_device *pdev)
1517{
1518 struct exynos5_dmc *dmc = dev_get_drvdata(&pdev->dev);
1519
1228 exynos5_counters_disable_edev(dmc);
1520 if (dmc->in_irq_mode)
1521 exynos5_dmc_disable_perf_events(dmc);
1522 else
1523 exynos5_counters_disable_edev(dmc);
1229
1230 clk_disable_unprepare(dmc->mout_bpll);
1231 clk_disable_unprepare(dmc->fout_bpll);
1232
1233 dev_pm_opp_remove_table(dmc->dev);
1234
1235 return 0;
1236}

--- 19 unchanged lines hidden ---
1524
1525 clk_disable_unprepare(dmc->mout_bpll);
1526 clk_disable_unprepare(dmc->fout_bpll);
1527
1528 dev_pm_opp_remove_table(dmc->dev);
1529
1530 return 0;
1531}

--- 19 unchanged lines hidden ---