diff options
Diffstat (limited to 'drivers/pwm/pwm-mediatek.c')
| -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 @@  #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]);  		}  	}  | 
