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>
This commit is contained in:
parent
61aa258ab1
commit
efecdeb82f
|
@ -35,25 +35,6 @@
|
|||
|
||||
#define PWM_CLK_DIV_MAX 7
|
||||
|
||||
enum {
|
||||
MTK_CLK_MAIN = 0,
|
||||
MTK_CLK_TOP,
|
||||
MTK_CLK_PWM1,
|
||||
MTK_CLK_PWM2,
|
||||
MTK_CLK_PWM3,
|
||||
MTK_CLK_PWM4,
|
||||
MTK_CLK_PWM5,
|
||||
MTK_CLK_PWM6,
|
||||
MTK_CLK_PWM7,
|
||||
MTK_CLK_PWM8,
|
||||
MTK_CLK_MAX,
|
||||
};
|
||||
|
||||
static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
|
||||
"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
|
||||
"pwm8"
|
||||
};
|
||||
|
||||
struct mtk_pwm_platform_data {
|
||||
unsigned int num_pwms;
|
||||
bool pwm45_fixup;
|
||||
|
@ -63,12 +44,17 @@ struct mtk_pwm_platform_data {
|
|||
* struct mtk_pwm_chip - struct representing PWM chip
|
||||
* @chip: linux PWM chip representation
|
||||
* @regs: base address of PWM chip
|
||||
* @clks: list of clocks
|
||||
* @clk_top: the top clock generator
|
||||
* @clk_main: the clock used by PWM core
|
||||
* @clk_pwms: the clock used by each PWM channel
|
||||
* @clk_freq: the fix clock frequency of legacy MIPS SoC
|
||||
*/
|
||||
struct mtk_pwm_chip {
|
||||
struct pwm_chip chip;
|
||||
void __iomem *regs;
|
||||
struct clk *clks[MTK_CLK_MAX];
|
||||
struct clk *clk_top;
|
||||
struct clk *clk_main;
|
||||
struct clk **clk_pwms;
|
||||
const struct mtk_pwm_platform_data *soc;
|
||||
};
|
||||
|
||||
|
@ -86,24 +72,24 @@ static int mtk_pwm_clk_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
|||
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(pc->clks[MTK_CLK_TOP]);
|
||||
ret = clk_prepare_enable(pc->clk_top);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(pc->clks[MTK_CLK_MAIN]);
|
||||
ret = clk_prepare_enable(pc->clk_main);
|
||||
if (ret < 0)
|
||||
goto disable_clk_top;
|
||||
|
||||
ret = clk_prepare_enable(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
|
||||
ret = clk_prepare_enable(pc->clk_pwms[pwm->hwpwm]);
|
||||
if (ret < 0)
|
||||
goto disable_clk_main;
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clk_main:
|
||||
clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
|
||||
clk_disable_unprepare(pc->clk_main);
|
||||
disable_clk_top:
|
||||
clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);
|
||||
clk_disable_unprepare(pc->clk_top);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -112,9 +98,9 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
|||
{
|
||||
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
|
||||
clk_disable_unprepare(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
|
||||
clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
|
||||
clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);
|
||||
clk_disable_unprepare(pc->clk_pwms[pwm->hwpwm]);
|
||||
clk_disable_unprepare(pc->clk_main);
|
||||
clk_disable_unprepare(pc->clk_top);
|
||||
}
|
||||
|
||||
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,
|
|||
int duty_ns, int period_ns)
|
||||
{
|
||||
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
struct clk *clk = pc->clks[MTK_CLK_PWM1 + pwm->hwpwm];
|
||||
struct clk *clk = pc->clk_pwms[pwm->hwpwm];
|
||||
u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH,
|
||||
reg_thres = PWMTHRES;
|
||||
u64 resolution;
|
||||
|
@ -235,12 +221,35 @@ static int mtk_pwm_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(pc->regs))
|
||||
return PTR_ERR(pc->regs);
|
||||
|
||||
for (i = 0; i < pc->soc->num_pwms + 2; i++) {
|
||||
pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
|
||||
if (IS_ERR(pc->clks[i])) {
|
||||
pc->clk_pwms = devm_kcalloc(&pdev->dev, pc->soc->num_pwms,
|
||||
sizeof(*pc->clk_pwms), GFP_KERNEL);
|
||||
if (!pc->clk_pwms)
|
||||
return -ENOMEM;
|
||||
|
||||
pc->clk_top = devm_clk_get(&pdev->dev, "top");
|
||||
if (IS_ERR(pc->clk_top)) {
|
||||
dev_err(&pdev->dev, "clock: top fail: %ld\n",
|
||||
PTR_ERR(pc->clk_top));
|
||||
return PTR_ERR(pc->clk_top);
|
||||
}
|
||||
|
||||
pc->clk_main = devm_clk_get(&pdev->dev, "main");
|
||||
if (IS_ERR(pc->clk_main)) {
|
||||
dev_err(&pdev->dev, "clock: main fail: %ld\n",
|
||||
PTR_ERR(pc->clk_main));
|
||||
return PTR_ERR(pc->clk_main);
|
||||
}
|
||||
|
||||
for (i = 0; i < pc->soc->num_pwms; i++) {
|
||||
char name[8];
|
||||
|
||||
snprintf(name, sizeof(name), "pwm%d", i + 1);
|
||||
|
||||
pc->clk_pwms[i] = devm_clk_get(&pdev->dev, name);
|
||||
if (IS_ERR(pc->clk_pwms[i])) {
|
||||
dev_err(&pdev->dev, "clock: %s fail: %ld\n",
|
||||
mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
|
||||
return PTR_ERR(pc->clks[i]);
|
||||
name, PTR_ERR(pc->clk_pwms[i]));
|
||||
return PTR_ERR(pc->clk_pwms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue