diff options
author | Sam Shih <sam.shih@mediatek.com> | 2019-09-19 18:49:04 -0400 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2019-09-25 03:49:15 -0400 |
commit | efecdeb82f21d4100566ce85bda2d7ffb9c9edff (patch) | |
tree | 12975cc3bfc25c14f5297f2fca9878d9c0a3f523 | |
parent | 61aa258ab1a50b834267f5df6cabef0d10f8955a (diff) |
pwm: mediatek: Allocate the clks array dynamically
Instead of using fixed size of arrays, allocate the memory for them
based on the number of PWMs specified for each SoC generation.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Sam Shih <sam.shih@mediatek.com>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
-rw-r--r-- | drivers/pwm/pwm-mediatek.c | 79 |
1 files changed, 44 insertions, 35 deletions
diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c index 9394735b0762..db986b77e556 100644 --- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c | |||
@@ -35,25 +35,6 @@ | |||
35 | 35 | ||
36 | #define PWM_CLK_DIV_MAX 7 | 36 | #define PWM_CLK_DIV_MAX 7 |
37 | 37 | ||
38 | enum { | ||
39 | MTK_CLK_MAIN = 0, | ||
40 | MTK_CLK_TOP, | ||
41 | MTK_CLK_PWM1, | ||
42 | MTK_CLK_PWM2, | ||
43 | MTK_CLK_PWM3, | ||
44 | MTK_CLK_PWM4, | ||
45 | MTK_CLK_PWM5, | ||
46 | MTK_CLK_PWM6, | ||
47 | MTK_CLK_PWM7, | ||
48 | MTK_CLK_PWM8, | ||
49 | MTK_CLK_MAX, | ||
50 | }; | ||
51 | |||
52 | static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = { | ||
53 | "main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7", | ||
54 | "pwm8" | ||
55 | }; | ||
56 | |||
57 | struct mtk_pwm_platform_data { | 38 | struct mtk_pwm_platform_data { |
58 | unsigned int num_pwms; | 39 | unsigned int num_pwms; |
59 | bool pwm45_fixup; | 40 | bool pwm45_fixup; |
@@ -63,12 +44,17 @@ struct mtk_pwm_platform_data { | |||
63 | * struct mtk_pwm_chip - struct representing PWM chip | 44 | * struct mtk_pwm_chip - struct representing PWM chip |
64 | * @chip: linux PWM chip representation | 45 | * @chip: linux PWM chip representation |
65 | * @regs: base address of PWM chip | 46 | * @regs: base address of PWM chip |
66 | * @clks: list of clocks | 47 | * @clk_top: the top clock generator |
48 | * @clk_main: the clock used by PWM core | ||
49 | * @clk_pwms: the clock used by each PWM channel | ||
50 | * @clk_freq: the fix clock frequency of legacy MIPS SoC | ||
67 | */ | 51 | */ |
68 | struct mtk_pwm_chip { | 52 | struct mtk_pwm_chip { |
69 | struct pwm_chip chip; | 53 | struct pwm_chip chip; |
70 | void __iomem *regs; | 54 | void __iomem *regs; |
71 | struct clk *clks[MTK_CLK_MAX]; | 55 | struct clk *clk_top; |
56 | struct clk *clk_main; | ||
57 | struct clk **clk_pwms; | ||
72 | const struct mtk_pwm_platform_data *soc; | 58 | const struct mtk_pwm_platform_data *soc; |
73 | }; | 59 | }; |
74 | 60 | ||
@@ -86,24 +72,24 @@ static int mtk_pwm_clk_enable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
86 | struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); | 72 | struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); |
87 | int ret; | 73 | int ret; |
88 | 74 | ||
89 | ret = clk_prepare_enable(pc->clks[MTK_CLK_TOP]); | 75 | ret = clk_prepare_enable(pc->clk_top); |
90 | if (ret < 0) | 76 | if (ret < 0) |
91 | return ret; | 77 | return ret; |
92 | 78 | ||
93 | ret = clk_prepare_enable(pc->clks[MTK_CLK_MAIN]); | 79 | ret = clk_prepare_enable(pc->clk_main); |
94 | if (ret < 0) | 80 | if (ret < 0) |
95 | goto disable_clk_top; | 81 | goto disable_clk_top; |
96 | 82 | ||
97 | ret = clk_prepare_enable(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]); | 83 | ret = clk_prepare_enable(pc->clk_pwms[pwm->hwpwm]); |
98 | if (ret < 0) | 84 | if (ret < 0) |
99 | goto disable_clk_main; | 85 | goto disable_clk_main; |
100 | 86 | ||
101 | return 0; | 87 | return 0; |
102 | 88 | ||
103 | disable_clk_main: | 89 | disable_clk_main: |
104 | clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]); | 90 | clk_disable_unprepare(pc->clk_main); |
105 | disable_clk_top: | 91 | disable_clk_top: |
106 | clk_disable_unprepare(pc->clks[MTK_CLK_TOP]); | 92 | clk_disable_unprepare(pc->clk_top); |
107 | 93 | ||
108 | return ret; | 94 | return ret; |
109 | } | 95 | } |
@@ -112,9 +98,9 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
112 | { | 98 | { |
113 | struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); | 99 | struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); |
114 | 100 | ||
115 | clk_disable_unprepare(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]); | 101 | clk_disable_unprepare(pc->clk_pwms[pwm->hwpwm]); |
116 | clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]); | 102 | clk_disable_unprepare(pc->clk_main); |
117 | clk_disable_unprepare(pc->clks[MTK_CLK_TOP]); | 103 | clk_disable_unprepare(pc->clk_top); |
118 | } | 104 | } |
119 | 105 | ||
120 | static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num, | 106 | static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num, |
@@ -134,7 +120,7 @@ static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
134 | int duty_ns, int period_ns) | 120 | int duty_ns, int period_ns) |
135 | { | 121 | { |
136 | struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); | 122 | struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); |
137 | struct clk *clk = pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]; | 123 | struct clk *clk = pc->clk_pwms[pwm->hwpwm]; |
138 | u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH, | 124 | u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH, |
139 | reg_thres = PWMTHRES; | 125 | reg_thres = PWMTHRES; |
140 | u64 resolution; | 126 | u64 resolution; |
@@ -235,12 +221,35 @@ static int mtk_pwm_probe(struct platform_device *pdev) | |||
235 | if (IS_ERR(pc->regs)) | 221 | if (IS_ERR(pc->regs)) |
236 | return PTR_ERR(pc->regs); | 222 | return PTR_ERR(pc->regs); |
237 | 223 | ||
238 | for (i = 0; i < pc->soc->num_pwms + 2; i++) { | 224 | pc->clk_pwms = devm_kcalloc(&pdev->dev, pc->soc->num_pwms, |
239 | pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]); | 225 | sizeof(*pc->clk_pwms), GFP_KERNEL); |
240 | if (IS_ERR(pc->clks[i])) { | 226 | if (!pc->clk_pwms) |
227 | return -ENOMEM; | ||
228 | |||
229 | pc->clk_top = devm_clk_get(&pdev->dev, "top"); | ||
230 | if (IS_ERR(pc->clk_top)) { | ||
231 | dev_err(&pdev->dev, "clock: top fail: %ld\n", | ||
232 | PTR_ERR(pc->clk_top)); | ||
233 | return PTR_ERR(pc->clk_top); | ||
234 | } | ||
235 | |||
236 | pc->clk_main = devm_clk_get(&pdev->dev, "main"); | ||
237 | if (IS_ERR(pc->clk_main)) { | ||
238 | dev_err(&pdev->dev, "clock: main fail: %ld\n", | ||
239 | PTR_ERR(pc->clk_main)); | ||
240 | return PTR_ERR(pc->clk_main); | ||
241 | } | ||
242 | |||
243 | for (i = 0; i < pc->soc->num_pwms; i++) { | ||
244 | char name[8]; | ||
245 | |||
246 | snprintf(name, sizeof(name), "pwm%d", i + 1); | ||
247 | |||
248 | pc->clk_pwms[i] = devm_clk_get(&pdev->dev, name); | ||
249 | if (IS_ERR(pc->clk_pwms[i])) { | ||
241 | dev_err(&pdev->dev, "clock: %s fail: %ld\n", | 250 | dev_err(&pdev->dev, "clock: %s fail: %ld\n", |
242 | mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i])); | 251 | name, PTR_ERR(pc->clk_pwms[i])); |
243 | return PTR_ERR(pc->clks[i]); | 252 | return PTR_ERR(pc->clk_pwms[i]); |
244 | } | 253 | } |
245 | } | 254 | } |
246 | 255 | ||