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
|
#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 {
|
struct mtk_pwm_platform_data {
|
||||||
unsigned int num_pwms;
|
unsigned int num_pwms;
|
||||||
bool pwm45_fixup;
|
bool pwm45_fixup;
|
||||||
|
@ -63,12 +44,17 @@ struct mtk_pwm_platform_data {
|
||||||
* struct mtk_pwm_chip - struct representing PWM chip
|
* struct mtk_pwm_chip - struct representing PWM chip
|
||||||
* @chip: linux PWM chip representation
|
* @chip: linux PWM chip representation
|
||||||
* @regs: base address of PWM chip
|
* @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 mtk_pwm_chip {
|
||||||
struct pwm_chip chip;
|
struct pwm_chip chip;
|
||||||
void __iomem *regs;
|
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;
|
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);
|
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = clk_prepare_enable(pc->clks[MTK_CLK_TOP]);
|
ret = clk_prepare_enable(pc->clk_top);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = clk_prepare_enable(pc->clks[MTK_CLK_MAIN]);
|
ret = clk_prepare_enable(pc->clk_main);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto disable_clk_top;
|
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)
|
if (ret < 0)
|
||||||
goto disable_clk_main;
|
goto disable_clk_main;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
disable_clk_main:
|
disable_clk_main:
|
||||||
clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
|
clk_disable_unprepare(pc->clk_main);
|
||||||
disable_clk_top:
|
disable_clk_top:
|
||||||
clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);
|
clk_disable_unprepare(pc->clk_top);
|
||||||
|
|
||||||
return ret;
|
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);
|
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||||
|
|
||||||
clk_disable_unprepare(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
|
clk_disable_unprepare(pc->clk_pwms[pwm->hwpwm]);
|
||||||
clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
|
clk_disable_unprepare(pc->clk_main);
|
||||||
clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);
|
clk_disable_unprepare(pc->clk_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
|
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)
|
int duty_ns, int period_ns)
|
||||||
{
|
{
|
||||||
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
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,
|
u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH,
|
||||||
reg_thres = PWMTHRES;
|
reg_thres = PWMTHRES;
|
||||||
u64 resolution;
|
u64 resolution;
|
||||||
|
@ -235,12 +221,35 @@ static int mtk_pwm_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(pc->regs))
|
if (IS_ERR(pc->regs))
|
||||||
return PTR_ERR(pc->regs);
|
return PTR_ERR(pc->regs);
|
||||||
|
|
||||||
for (i = 0; i < pc->soc->num_pwms + 2; i++) {
|
pc->clk_pwms = devm_kcalloc(&pdev->dev, pc->soc->num_pwms,
|
||||||
pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
|
sizeof(*pc->clk_pwms), GFP_KERNEL);
|
||||||
if (IS_ERR(pc->clks[i])) {
|
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",
|
dev_err(&pdev->dev, "clock: %s fail: %ld\n",
|
||||||
mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
|
name, PTR_ERR(pc->clk_pwms[i]));
|
||||||
return PTR_ERR(pc->clks[i]);
|
return PTR_ERR(pc->clk_pwms[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue