diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-13 20:51:39 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-13 20:51:39 +0300 |
commit | aeb152910a7aecabde5c5f0477a08b397e94059c (patch) | |
tree | 9509c6f14816048c1ae8f7d4b9ec8ee825c0d2f6 /drivers/pwm/pwm-vt8500.c | |
parent | aa7d6513d68bad539142f9d6c3e2faa629bc27d8 (diff) | |
parent | dd6c6d57ab61d496f6ff7d6ca38611062af142a1 (diff) | |
download | linux-aeb152910a7aecabde5c5f0477a08b397e94059c.tar.xz |
Merge tag 'pwm/for-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux
Pull pwm updates from Uwe Kleine-König:
"This contains the usual amount of driver and device tree changes.
Additionally there is a big rework of how pwm lowlevel drivers are
registered to prepare adding character device support.
Thanks to Dharma Balasubiramani, Dong Aisheng, Duje Mihanović, Jerome
Brunet, Raag Jadav and Rafał Miłecki for their contributions. And
sorry for those who still need some patience because I didn't manage
to empty my review queue"
* tag 'pwm/for-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux: (185 commits)
pwm: imx-tpm: fix probe crash due to access registers without clock
pwm: meson: generalize 4 inputs clock on meson8 pwm type
dt-bindings: pwm: amlogic: Add a new binding for meson8 pwm types
dt-bindings: pwm: amlogic: fix s4 bindings
pwm: dwc: simplify error handling
pwm: dwc: Add 16 channel support for Intel Elkhart Lake
pwm: dwc: drop redundant error check
staging: greybus: pwm: Make use of devm_pwmchip_alloc() function
staging: greybus: pwm: Rework how the number of PWM lines is determined
staging: greybus: pwm: Drop unused gb_connection_set_data()
staging: greybus: pwm: Rely on pwm framework to pass a valid hwpwm
staging: greybus: pwm: Make use of pwmchip_parent() accessor
staging: greybus: pwm: Change prototype of helpers to prepare further changes
leds: qcom-lpg: Make use of devm_pwmchip_alloc() function
drm/bridge: ti-sn65dsi86: Make use of devm_pwmchip_alloc() function
drm/bridge: ti-sn65dsi86: Make use of pwmchip_parent() accessor
gpio: mvebu: Make use of devm_pwmchip_alloc() function
pwm: xilinx: Make use of devm_pwmchip_alloc() function
pwm: xilinx: Prepare removing pwm_chip from driver data
pwm: vt8500: Make use of devm_pwmchip_alloc() function
...
Diffstat (limited to 'drivers/pwm/pwm-vt8500.c')
-rw-r--r-- | drivers/pwm/pwm-vt8500.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c index 7bfeacee05d0..016c82d65527 100644 --- a/drivers/pwm/pwm-vt8500.c +++ b/drivers/pwm/pwm-vt8500.c @@ -45,16 +45,19 @@ #define STATUS_ALL_UPDATE 0x0F struct vt8500_chip { - struct pwm_chip chip; void __iomem *base; struct clk *clk; }; -#define to_vt8500_chip(chip) container_of(chip, struct vt8500_chip, chip) +static inline struct vt8500_chip *to_vt8500_chip(struct pwm_chip *chip) +{ + return pwmchip_get_drvdata(chip); +} #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) -static inline void vt8500_pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 bitmask) +static inline void vt8500_pwm_busy_wait(struct pwm_chip *chip, int nr, u8 bitmask) { + struct vt8500_chip *vt8500 = to_vt8500_chip(chip); int loops = msecs_to_loops(10); u32 mask = bitmask << (nr << 8); @@ -62,7 +65,7 @@ static inline void vt8500_pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 b cpu_relax(); if (unlikely(!loops)) - dev_warn(vt8500->chip.dev, "Waiting for status bits 0x%x to clear timed out\n", + dev_warn(pwmchip_parent(chip), "Waiting for status bits 0x%x to clear timed out\n", mask); } @@ -77,7 +80,7 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, err = clk_enable(vt8500->clk); if (err < 0) { - dev_err(chip->dev, "failed to enable clock\n"); + dev_err(pwmchip_parent(chip), "failed to enable clock\n"); return err; } @@ -103,18 +106,18 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, dc = div64_u64(c, period_ns); writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_SCALAR_UPDATE); writel(pv, vt8500->base + REG_PERIOD(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_PERIOD_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_PERIOD_UPDATE); writel(dc, vt8500->base + REG_DUTY(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_DUTY_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_DUTY_UPDATE); val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); val |= CTRL_AUTOLOAD; writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE); clk_disable(vt8500->clk); return 0; @@ -128,14 +131,14 @@ static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) err = clk_enable(vt8500->clk); if (err < 0) { - dev_err(chip->dev, "failed to enable clock\n"); + dev_err(pwmchip_parent(chip), "failed to enable clock\n"); return err; } val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); val |= CTRL_ENABLE; writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE); return 0; } @@ -148,7 +151,7 @@ static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); val &= ~CTRL_ENABLE; writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE); clk_disable(vt8500->clk); } @@ -168,7 +171,7 @@ static int vt8500_pwm_set_polarity(struct pwm_chip *chip, val &= ~CTRL_INVERT; writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE); return 0; } @@ -231,6 +234,7 @@ MODULE_DEVICE_TABLE(of, vt8500_pwm_dt_ids); static int vt8500_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct vt8500_chip *vt8500; struct device_node *np = pdev->dev.of_node; int ret; @@ -238,13 +242,12 @@ static int vt8500_pwm_probe(struct platform_device *pdev) if (!np) return dev_err_probe(&pdev->dev, -EINVAL, "invalid devicetree node\n"); - vt8500 = devm_kzalloc(&pdev->dev, sizeof(*vt8500), GFP_KERNEL); - if (vt8500 == NULL) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, VT8500_NR_PWMS, sizeof(*vt8500)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + vt8500 = to_vt8500_chip(chip); - vt8500->chip.dev = &pdev->dev; - vt8500->chip.ops = &vt8500_pwm_ops; - vt8500->chip.npwm = VT8500_NR_PWMS; + chip->ops = &vt8500_pwm_ops; vt8500->clk = devm_clk_get_prepared(&pdev->dev, NULL); if (IS_ERR(vt8500->clk)) @@ -254,7 +257,7 @@ static int vt8500_pwm_probe(struct platform_device *pdev) if (IS_ERR(vt8500->base)) return PTR_ERR(vt8500->base); - ret = devm_pwmchip_add(&pdev->dev, &vt8500->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n"); |