diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:11:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:11:40 +0000 |
commit | 8b0a8165cdad0f4133837d753649ef4682e42c3b (patch) | |
tree | 5c58f869f31ddb1f7bd6e8bdea269b680b36c5b6 /drivers/pwm/pwm-sprd.c | |
parent | Releasing progress-linux version 6.8.12-1~progress7.99u1. (diff) | |
download | linux-8b0a8165cdad0f4133837d753649ef4682e42c3b.tar.xz linux-8b0a8165cdad0f4133837d753649ef4682e42c3b.zip |
Merging upstream version 6.9.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/pwm/pwm-sprd.c')
-rw-r--r-- | drivers/pwm/pwm-sprd.c | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/drivers/pwm/pwm-sprd.c b/drivers/pwm/pwm-sprd.c index 77939e1610..4c76ca5e4c 100644 --- a/drivers/pwm/pwm-sprd.c +++ b/drivers/pwm/pwm-sprd.c @@ -34,15 +34,12 @@ struct sprd_pwm_chn { struct sprd_pwm_chip { void __iomem *base; - struct device *dev; - struct pwm_chip chip; - int num_pwms; struct sprd_pwm_chn chn[SPRD_PWM_CHN_NUM]; }; static inline struct sprd_pwm_chip* sprd_pwm_from_chip(struct pwm_chip *chip) { - return container_of(chip, struct sprd_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } /* @@ -86,7 +83,7 @@ static int sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, */ ret = clk_bulk_prepare_enable(SPRD_PWM_CHN_CLKS_NUM, chn->clks); if (ret) { - dev_err(spc->dev, "failed to enable pwm%u clocks\n", + dev_err(pwmchip_parent(chip), "failed to enable pwm%u clocks\n", pwm->hwpwm); return ret; } @@ -183,7 +180,7 @@ static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ret = clk_bulk_prepare_enable(SPRD_PWM_CHN_CLKS_NUM, chn->clks); if (ret) { - dev_err(spc->dev, + dev_err(pwmchip_parent(chip), "failed to enable pwm%u clocks\n", pwm->hwpwm); return ret; @@ -215,65 +212,64 @@ static const struct pwm_ops sprd_pwm_ops = { .get_state = sprd_pwm_get_state, }; -static int sprd_pwm_clk_init(struct sprd_pwm_chip *spc) +static int sprd_pwm_clk_init(struct device *dev, + struct sprd_pwm_chn chn[SPRD_PWM_CHN_NUM]) { struct clk *clk_pwm; int ret, i; for (i = 0; i < SPRD_PWM_CHN_NUM; i++) { - struct sprd_pwm_chn *chn = &spc->chn[i]; int j; for (j = 0; j < SPRD_PWM_CHN_CLKS_NUM; ++j) - chn->clks[j].id = + chn[i].clks[j].id = sprd_pwm_clks[i * SPRD_PWM_CHN_CLKS_NUM + j]; - ret = devm_clk_bulk_get(spc->dev, SPRD_PWM_CHN_CLKS_NUM, - chn->clks); + ret = devm_clk_bulk_get(dev, SPRD_PWM_CHN_CLKS_NUM, + chn[i].clks); if (ret) { if (ret == -ENOENT) break; - return dev_err_probe(spc->dev, ret, + return dev_err_probe(dev, ret, "failed to get channel clocks\n"); } - clk_pwm = chn->clks[SPRD_PWM_CHN_OUTPUT_CLK].clk; - chn->clk_rate = clk_get_rate(clk_pwm); + clk_pwm = chn[i].clks[SPRD_PWM_CHN_OUTPUT_CLK].clk; + chn[i].clk_rate = clk_get_rate(clk_pwm); } if (!i) - return dev_err_probe(spc->dev, -ENODEV, "no available PWM channels\n"); + return dev_err_probe(dev, -ENODEV, "no available PWM channels\n"); - spc->num_pwms = i; - - return 0; + return i; } static int sprd_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct sprd_pwm_chip *spc; - int ret; + struct sprd_pwm_chn chn[SPRD_PWM_CHN_NUM]; + int ret, npwm; - spc = devm_kzalloc(&pdev->dev, sizeof(*spc), GFP_KERNEL); - if (!spc) - return -ENOMEM; + npwm = sprd_pwm_clk_init(&pdev->dev, chn); + if (npwm < 0) + return npwm; + + chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*spc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + spc = sprd_pwm_from_chip(chip); spc->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(spc->base)) return PTR_ERR(spc->base); - spc->dev = &pdev->dev; - - ret = sprd_pwm_clk_init(spc); - if (ret) - return ret; + memcpy(spc->chn, chn, sizeof(chn)); - spc->chip.dev = &pdev->dev; - spc->chip.ops = &sprd_pwm_ops; - spc->chip.npwm = spc->num_pwms; + chip->ops = &sprd_pwm_ops; - ret = devm_pwmchip_add(&pdev->dev, &spc->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret) dev_err(&pdev->dev, "failed to add PWM chip\n"); |