diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2023-07-05 10:06:43 +0200 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2023-10-13 10:07:17 +0200 |
commit | 1b2af7bb7523a86d0ab1f1a5e8d65063d08c7856 (patch) | |
tree | 1fa13e0ba8b99c36c48dbdebf78b718fe3175332 /drivers/pwm | |
parent | pwm: crc: Allow compilation as module and with COMPILE_TEST (diff) | |
download | linux-1b2af7bb7523a86d0ab1f1a5e8d65063d08c7856.tar.xz linux-1b2af7bb7523a86d0ab1f1a5e8d65063d08c7856.zip |
pwm: berlin: Put per-channel config into driver data
Instead of allocating extra data in .request() provide the needed memory
in struct berlin_pwm_chip. This reduces the number of allocations. A
side effect is that on suspend and resume the state for all four
channels is always saved and restored. This is easier (and probably
quicker) than looking up the matching pwm_device and checking its
PWMF_REQUESTED bit.
Link: https://lore.kernel.org/r/20230705080650.2353391-2-u.kleine-koenig@pengutronix.de
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/pwm-berlin.c | 37 |
1 files changed, 6 insertions, 31 deletions
diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c index 6a6641fc4fa1..832cb5995d18 100644 --- a/drivers/pwm/pwm-berlin.c +++ b/drivers/pwm/pwm-berlin.c @@ -39,6 +39,8 @@ #define BERLIN_PWM_TCNT 0xc #define BERLIN_PWM_MAX_TCNT 65535 +#define BERLIN_PWM_NUMPWMS 4 + struct berlin_pwm_channel { u32 enable; u32 ctrl; @@ -50,6 +52,7 @@ struct berlin_pwm_chip { struct pwm_chip chip; struct clk *clk; void __iomem *base; + struct berlin_pwm_channel channel[BERLIN_PWM_NUMPWMS]; }; static inline struct berlin_pwm_chip *to_berlin_pwm_chip(struct pwm_chip *chip) @@ -70,24 +73,6 @@ static inline void berlin_pwm_writel(struct berlin_pwm_chip *bpc, writel_relaxed(value, bpc->base + channel * 0x10 + offset); } -static int berlin_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct berlin_pwm_channel *channel; - - channel = kzalloc(sizeof(*channel), GFP_KERNEL); - if (!channel) - return -ENOMEM; - - return pwm_set_chip_data(pwm, channel); -} - -static void berlin_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct berlin_pwm_channel *channel = pwm_get_chip_data(pwm); - - kfree(channel); -} - static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, u64 duty_ns, u64 period_ns) { @@ -202,8 +187,6 @@ static int berlin_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, } static const struct pwm_ops berlin_pwm_ops = { - .request = berlin_pwm_request, - .free = berlin_pwm_free, .apply = berlin_pwm_apply, }; @@ -236,7 +219,7 @@ static int berlin_pwm_probe(struct platform_device *pdev) bpc->chip.dev = &pdev->dev; bpc->chip.ops = &berlin_pwm_ops; - bpc->chip.npwm = 4; + bpc->chip.npwm = BERLIN_PWM_NUMPWMS; ret = pwmchip_add(&bpc->chip); if (ret < 0) { @@ -266,11 +249,7 @@ static int berlin_pwm_suspend(struct device *dev) unsigned int i; for (i = 0; i < bpc->chip.npwm; i++) { - struct berlin_pwm_channel *channel; - - channel = pwm_get_chip_data(&bpc->chip.pwms[i]); - if (!channel) - continue; + struct berlin_pwm_channel *channel = &bpc->channel[i]; channel->enable = berlin_pwm_readl(bpc, i, BERLIN_PWM_ENABLE); channel->ctrl = berlin_pwm_readl(bpc, i, BERLIN_PWM_CONTROL); @@ -294,11 +273,7 @@ static int berlin_pwm_resume(struct device *dev) return ret; for (i = 0; i < bpc->chip.npwm; i++) { - struct berlin_pwm_channel *channel; - - channel = pwm_get_chip_data(&bpc->chip.pwms[i]); - if (!channel) - continue; + struct berlin_pwm_channel *channel = &bpc->channel[i]; berlin_pwm_writel(bpc, i, channel->ctrl, BERLIN_PWM_CONTROL); berlin_pwm_writel(bpc, i, channel->duty, BERLIN_PWM_DUTY); |