Commit 6701e7e7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pwm/for-5.15-rc1' of...

Merge tag 'pwm/for-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm

Pull pwm updates from Thierry Reding:
 "The changes this time around are mostly janitorial in nature. A lot of
  this is simplifications of drivers using device-managed functions and
  improving compilation coverage.

  The Mediatek display PWM driver now supports the atomic API.

  Cleanups and minor fixes make up the remainder of this set"

* tag 'pwm/for-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (54 commits)
  pwm: mtk-disp: Implement atomic API .get_state()
  pwm: mtk-disp: Fix overflow in period and duty calculation
  pwm: mtk-disp: Implement atomic API .apply()
  pwm: mtk-disp: Adjust the clocks to avoid them mismatch
  dt-bindings: pwm: rockchip: Add description for rk3568
  pwm: Make pwmchip_remove() return void
  pwm: sun4i: Don't check the return code of pwmchip_remove()
  pwm: sifive: Don't check the return code of pwmchip_remove()
  pwm: samsung: Don't check the return code of pwmchip_remove()
  pwm: renesas-tpu: Don't check the return code of pwmchip_remove()
  pwm: rcar: Don't check the return code of pwmchip_remove()
  pwm: pca9685: Don't check the return code of pwmchip_remove()
  pwm: omap-dmtimer: Don't check the return code of pwmchip_remove()
  pwm: mtk-disp: Don't check the return code of pwmchip_remove()
  pwm: imx-tpm: Don't check the return code of pwmchip_remove()
  pwm: img: Don't check the return code of pwmchip_remove()
  pwm: cros-ec: Don't check the return code of pwmchip_remove()
  pwm: brcmstb: Don't check the return code of pwmchip_remove()
  pwm: atmel-tcb: Don't check the return code of pwmchip_remove()
  pwm: atmel-hlcdc: Don't check the return code of pwmchip_remove()
  ...
parents dd470387 3f2b1673
......@@ -29,6 +29,7 @@ properties:
- enum:
- rockchip,px30-pwm
- rockchip,rk3308-pwm
- rockchip,rk3568-pwm
- const: rockchip,rk3328-pwm
reg:
......
......@@ -272,7 +272,7 @@ config PWM_IQS620A
config PWM_JZ4740
tristate "Ingenic JZ47xx PWM support"
depends on MIPS
depends on MIPS || COMPILE_TEST
depends on COMMON_CLK
select MFD_SYSCON
help
......@@ -284,7 +284,8 @@ config PWM_JZ4740
config PWM_KEEMBAY
tristate "Intel Keem Bay PWM driver"
depends on ARCH_KEEMBAY || (ARM64 && COMPILE_TEST)
depends on ARCH_KEEMBAY || COMPILE_TEST
depends on COMMON_CLK && HAS_IOMEM
help
The platform driver for Intel Keem Bay PWM controller.
......
......@@ -304,7 +304,7 @@ EXPORT_SYMBOL_GPL(pwmchip_add);
*
* Returns: 0 on success or a negative error code on failure.
*/
int pwmchip_remove(struct pwm_chip *chip)
void pwmchip_remove(struct pwm_chip *chip)
{
pwmchip_sysfs_unexport(chip);
......@@ -318,8 +318,6 @@ int pwmchip_remove(struct pwm_chip *chip)
free_pwms(chip);
mutex_unlock(&pwm_lock);
return 0;
}
EXPORT_SYMBOL_GPL(pwmchip_remove);
......
......@@ -22,14 +22,21 @@
struct ab8500_pwm_chip {
struct pwm_chip chip;
unsigned int hwid;
};
static struct ab8500_pwm_chip *ab8500_pwm_from_chip(struct pwm_chip *chip)
{
return container_of(chip, struct ab8500_pwm_chip, chip);
}
static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
int ret;
u8 reg;
unsigned int higher_val, lower_val;
struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip);
if (state->polarity != PWM_POLARITY_NORMAL)
return -EINVAL;
......@@ -37,7 +44,7 @@ static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
if (!state->enabled) {
ret = abx500_mask_and_set_register_interruptible(chip->dev,
AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
1 << (chip->base - 1), 0);
1 << ab8500->hwid, 0);
if (ret < 0)
dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
......@@ -56,7 +63,7 @@ static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
*/
higher_val = ((state->duty_cycle & 0x0300) >> 8);
reg = AB8500_PWM_OUT_CTRL1_REG + ((chip->base - 1) * 2);
reg = AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2);
ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC,
reg, (u8)lower_val);
......@@ -70,7 +77,7 @@ static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
ret = abx500_mask_and_set_register_interruptible(chip->dev,
AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
1 << (chip->base - 1), 1 << (chip->base - 1));
1 << ab8500->hwid, 1 << ab8500->hwid);
if (ret < 0)
dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n",
pwm->label, ret);
......@@ -88,6 +95,9 @@ static int ab8500_pwm_probe(struct platform_device *pdev)
struct ab8500_pwm_chip *ab8500;
int err;
if (pdev->id < 1 || pdev->id > 31)
return dev_err_probe(&pdev->dev, EINVAL, "Invalid device id %d\n", pdev->id);
/*
* Nothing to be done in probe, this is required to get the
* device which is required for ab8500 read and write
......@@ -99,27 +109,13 @@ static int ab8500_pwm_probe(struct platform_device *pdev)
ab8500->chip.dev = &pdev->dev;
ab8500->chip.ops = &ab8500_pwm_ops;
ab8500->chip.npwm = 1;
ab8500->hwid = pdev->id - 1;
err = pwmchip_add(&ab8500->chip);
err = devm_pwmchip_add(&pdev->dev, &ab8500->chip);
if (err < 0)
return dev_err_probe(&pdev->dev, err, "Failed to add pwm chip\n");
dev_dbg(&pdev->dev, "pwm probe successful\n");
platform_set_drvdata(pdev, ab8500);
return 0;
}
static int ab8500_pwm_remove(struct platform_device *pdev)
{
struct ab8500_pwm_chip *ab8500 = platform_get_drvdata(pdev);
int err;
err = pwmchip_remove(&ab8500->chip);
if (err < 0)
return err;
dev_dbg(&pdev->dev, "pwm driver removed\n");
return 0;
}
......@@ -129,7 +125,6 @@ static struct platform_driver ab8500_pwm_driver = {
.name = "ab8500-pwm",
},
.probe = ab8500_pwm_probe,
.remove = ab8500_pwm_remove,
};
module_platform_driver(ab8500_pwm_driver);
......
......@@ -281,11 +281,8 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
static int atmel_hlcdc_pwm_remove(struct platform_device *pdev)
{
struct atmel_hlcdc_pwm *chip = platform_get_drvdata(pdev);
int ret;
ret = pwmchip_remove(&chip->chip);
if (ret)
return ret;
pwmchip_remove(&chip->chip);
clk_disable_unprepare(chip->hlcdc->periph_clk);
......
......@@ -503,11 +503,8 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
static int atmel_tcb_pwm_remove(struct platform_device *pdev)
{
struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
int err;
err = pwmchip_remove(&tcbpwm->chip);
if (err < 0)
return err;
pwmchip_remove(&tcbpwm->chip);
clk_disable_unprepare(tcbpwm->slow_clk);
clk_put(tcbpwm->slow_clk);
......
......@@ -84,9 +84,19 @@ struct atmel_pwm_chip {
void __iomem *base;
const struct atmel_pwm_data *data;
unsigned int updated_pwms;
/* ISR is cleared when read, ensure only one thread does that */
struct mutex isr_lock;
/*
* The hardware supports a mechanism to update a channel's duty cycle at
* the end of the currently running period. When such an update is
* pending we delay disabling the PWM until the new configuration is
* active because otherwise pmw_config(duty_cycle=0); pwm_disable();
* might not result in an inactive output.
* This bitmask tracks for which channels an update is pending in
* hardware.
*/
u32 update_pending;
/* Protects .update_pending */
spinlock_t lock;
};
static inline struct atmel_pwm_chip *to_atmel_pwm_chip(struct pwm_chip *chip)
......@@ -123,6 +133,64 @@ static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip,
atmel_pwm_writel(chip, base + offset, val);
}
static void atmel_pwm_update_pending(struct atmel_pwm_chip *chip)
{
/*
* Each channel that has its bit in ISR set started a new period since
* ISR was cleared and so there is no more update pending. Note that
* reading ISR clears it, so this needs to handle all channels to not
* loose information.
*/
u32 isr = atmel_pwm_readl(chip, PWM_ISR);
chip->update_pending &= ~isr;
}
static void atmel_pwm_set_pending(struct atmel_pwm_chip *chip, unsigned int ch)
{
spin_lock(&chip->lock);
/*
* Clear pending flags in hardware because otherwise there might still
* be a stale flag in ISR.
*/
atmel_pwm_update_pending(chip);
chip->update_pending |= (1 << ch);
spin_unlock(&chip->lock);
}
static int atmel_pwm_test_pending(struct atmel_pwm_chip *chip, unsigned int ch)
{
int ret = 0;
spin_lock(&chip->lock);
if (chip->update_pending & (1 << ch)) {
atmel_pwm_update_pending(chip);
if (chip->update_pending & (1 << ch))
ret = 1;
}
spin_unlock(&chip->lock);
return ret;
}
static int atmel_pwm_wait_nonpending(struct atmel_pwm_chip *chip, unsigned int ch)
{
unsigned long timeout = jiffies + 2 * HZ;
int ret;
while ((ret = atmel_pwm_test_pending(chip, ch)) &&
time_before(jiffies, timeout))
usleep_range(10, 100);
return ret ? -ETIMEDOUT : 0;
}
static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
unsigned long clkrate,
const struct pwm_state *state,
......@@ -185,6 +253,7 @@ static void atmel_pwm_update_cdty(struct pwm_chip *chip, struct pwm_device *pwm,
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
atmel_pwm->data->regs.duty_upd, cdty);
atmel_pwm_set_pending(atmel_pwm, pwm->hwpwm);
}
static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
......@@ -205,20 +274,8 @@ static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm,
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
unsigned long timeout = jiffies + 2 * HZ;
/*
* Wait for at least a complete period to have passed before disabling a
* channel to be sure that CDTY has been updated
*/
mutex_lock(&atmel_pwm->isr_lock);
atmel_pwm->updated_pwms |= atmel_pwm_readl(atmel_pwm, PWM_ISR);
while (!(atmel_pwm->updated_pwms & (1 << pwm->hwpwm)) &&
time_before(jiffies, timeout)) {
usleep_range(10, 100);
atmel_pwm->updated_pwms |= atmel_pwm_readl(atmel_pwm, PWM_ISR);
}
atmel_pwm_wait_nonpending(atmel_pwm, pwm->hwpwm);
mutex_unlock(&atmel_pwm->isr_lock);
atmel_pwm_writel(atmel_pwm, PWM_DIS, 1 << pwm->hwpwm);
/*
......@@ -292,10 +349,6 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
val |= PWM_CMR_CPOL;
atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
atmel_pwm_set_cprd_cdty(chip, pwm, cprd, cdty);
mutex_lock(&atmel_pwm->isr_lock);
atmel_pwm->updated_pwms |= atmel_pwm_readl(atmel_pwm, PWM_ISR);
atmel_pwm->updated_pwms &= ~(1 << pwm->hwpwm);
mutex_unlock(&atmel_pwm->isr_lock);
atmel_pwm_writel(atmel_pwm, PWM_ENA, 1 << pwm->hwpwm);
} else if (cstate.enabled) {
atmel_pwm_disable(chip, pwm, true);
......@@ -326,6 +379,9 @@ static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
tmp <<= pres;
state->period = DIV64_U64_ROUND_UP(tmp, rate);
/* Wait for an updated duty_cycle queued in hardware */
atmel_pwm_wait_nonpending(atmel_pwm, pwm->hwpwm);
cdty = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
atmel_pwm->data->regs.duty);
tmp = (u64)(cprd - cdty) * NSEC_PER_SEC;
......@@ -416,9 +472,10 @@ static int atmel_pwm_probe(struct platform_device *pdev)
if (!atmel_pwm)
return -ENOMEM;
mutex_init(&atmel_pwm->isr_lock);
atmel_pwm->data = of_device_get_match_data(&pdev->dev);
atmel_pwm->updated_pwms = 0;
atmel_pwm->update_pending = 0;
spin_lock_init(&atmel_pwm->lock);
atmel_pwm->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(atmel_pwm->base))
......@@ -460,7 +517,6 @@ static int atmel_pwm_remove(struct platform_device *pdev)
pwmchip_remove(&atmel_pwm->chip);
clk_unprepare(atmel_pwm->clk);
mutex_destroy(&atmel_pwm->isr_lock);
return 0;
}
......
......@@ -267,8 +267,6 @@ static int kona_pwmc_probe(struct platform_device *pdev)
if (kp == NULL)
return -ENOMEM;
platform_set_drvdata(pdev, kp);
kp->chip.dev = &pdev->dev;
kp->chip.ops = &kona_pwm_ops;
kp->chip.npwm = 6;
......@@ -298,20 +296,13 @@ static int kona_pwmc_probe(struct platform_device *pdev)
clk_disable_unprepare(kp->clk);
ret = pwmchip_add(&kp->chip);
ret = devm_pwmchip_add(&pdev->dev, &kp->chip);
if (ret < 0)
dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
return ret;
}
static int kona_pwmc_remove(struct platform_device *pdev)
{
struct kona_pwmc *kp = platform_get_drvdata(pdev);
return pwmchip_remove(&kp->chip);
}
static const struct of_device_id bcm_kona_pwmc_dt[] = {
{ .compatible = "brcm,kona-pwm" },
{ },
......@@ -324,7 +315,6 @@ static struct platform_driver kona_pwmc_driver = {
.of_match_table = bcm_kona_pwmc_dt,
},
.probe = kona_pwmc_probe,
.remove = kona_pwmc_remove,
};
module_platform_driver(kona_pwmc_driver);
......
......@@ -282,12 +282,11 @@ static int brcmstb_pwm_probe(struct platform_device *pdev)
static int brcmstb_pwm_remove(struct platform_device *pdev)
{
struct brcmstb_pwm *p = platform_get_drvdata(pdev);
int ret;
ret = pwmchip_remove(&p->chip);
pwmchip_remove(&p->chip);
clk_disable_unprepare(p->clk);
return ret;
return 0;
}
#ifdef CONFIG_PM_SLEEP
......
......@@ -280,7 +280,9 @@ static int cros_ec_pwm_remove(struct platform_device *dev)
struct cros_ec_pwm_device *ec_pwm = platform_get_drvdata(dev);
struct pwm_chip *chip = &ec_pwm->chip;
return pwmchip_remove(chip);
pwmchip_remove(chip);
return 0;
}
#ifdef CONFIG_OF
......
......@@ -183,27 +183,18 @@ static int ep93xx_pwm_probe(struct platform_device *pdev)
ep93xx_pwm->chip.ops = &ep93xx_pwm_ops;
ep93xx_pwm->chip.npwm = 1;
ret = pwmchip_add(&ep93xx_pwm->chip);
ret = devm_pwmchip_add(&pdev->dev, &ep93xx_pwm->chip);
if (ret < 0)
return ret;
platform_set_drvdata(pdev, ep93xx_pwm);
return 0;
}
static int ep93xx_pwm_remove(struct platform_device *pdev)
{
struct ep93xx_pwm *ep93xx_pwm = platform_get_drvdata(pdev);
return pwmchip_remove(&ep93xx_pwm->chip);
}
static struct platform_driver ep93xx_pwm_driver = {
.driver = {
.name = "ep93xx-pwm",
},
.probe = ep93xx_pwm_probe,
.remove = ep93xx_pwm_remove,
};
module_platform_driver(ep93xx_pwm_driver);
......
......@@ -453,7 +453,7 @@ static int fsl_pwm_probe(struct platform_device *pdev)
fpc->chip.ops = &fsl_pwm_ops;
fpc->chip.npwm = 8;
ret = pwmchip_add(&fpc->chip);
ret = devm_pwmchip_add(&pdev->dev, &fpc->chip);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
return ret;
......@@ -464,13 +464,6 @@ static int fsl_pwm_probe(struct platform_device *pdev)
return fsl_pwm_init(fpc);
}
static int fsl_pwm_remove(struct platform_device *pdev)
{
struct fsl_pwm_chip *fpc = platform_get_drvdata(pdev);
return pwmchip_remove(&fpc->chip);
}
#ifdef CONFIG_PM_SLEEP
static int fsl_pwm_suspend(struct device *dev)
{
......@@ -552,7 +545,6 @@ static struct platform_driver fsl_pwm_driver = {
.pm = &fsl_pwm_pm_ops,
},
.probe = fsl_pwm_probe,
.remove = fsl_pwm_remove,
};
module_platform_driver(fsl_pwm_driver);
......
......@@ -248,13 +248,15 @@ static int hibvt_pwm_remove(struct platform_device *pdev)
pwm_chip = platform_get_drvdata(pdev);
pwmchip_remove(&pwm_chip->chip);
reset_control_assert(pwm_chip->rstc);
msleep(30);
reset_control_deassert(pwm_chip->rstc);
clk_disable_unprepare(pwm_chip->clk);
return pwmchip_remove(&pwm_chip->chip);
return 0;
}
static const struct of_device_id hibvt_pwm_of_match[] = {
......
......@@ -326,28 +326,14 @@ static int img_pwm_probe(struct platform_device *pdev)
static int img_pwm_remove(struct platform_device *pdev)
{
struct img_pwm_chip *pwm_chip = platform_get_drvdata(pdev);
u32 val;
unsigned int i;
int ret;
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0) {
pm_runtime_put(&pdev->dev);
return ret;
}
for (i = 0; i < pwm_chip->chip.npwm; i++) {
val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
val &= ~BIT(i);
img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val);
}
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
img_pwm_runtime_suspend(&pdev->dev);
return pwmchip_remove(&pwm_chip->chip);
pwmchip_remove(&pwm_chip->chip);
return 0;
}
#ifdef CONFIG_PM_SLEEP
......
......@@ -382,11 +382,12 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
static int pwm_imx_tpm_remove(struct platform_device *pdev)
{
struct imx_tpm_pwm_chip *tpm = platform_get_drvdata(pdev);
int ret = pwmchip_remove(&tpm->chip);
pwmchip_remove(&tpm->chip);
clk_disable_unprepare(tpm->clk);
return ret;
return 0;
}
static int __maybe_unused pwm_imx_tpm_suspend(struct device *dev)
......
......@@ -313,8 +313,6 @@ static int pwm_imx27_probe(struct platform_device *pdev)
if (imx == NULL)
return -ENOMEM;
platform_set_drvdata(pdev, imx);
imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(imx->clk_ipg))
return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_ipg),
......@@ -342,16 +340,7 @@ static int pwm_imx27_probe(struct platform_device *pdev)
if (!(pwmcr & MX3_PWMCR_EN))
pwm_imx27_clk_disable_unprepare(imx);
return pwmchip_add(&imx->chip);
}
static int pwm_imx27_remove(struct platform_device *pdev)
{
struct pwm_imx27_chip *imx;
imx = platform_get_drvdata(pdev);
return pwmchip_remove(&imx->chip);
return devm_pwmchip_add(&pdev->dev, &imx->chip);
}
static struct platform_driver imx_pwm_driver = {
......@@ -360,7 +349,6 @@ static struct platform_driver imx_pwm_driver = {
.of_match_table = pwm_imx27_dt_ids,
},
.probe = pwm_imx27_probe,
.remove = pwm_imx27_remove,
};
module_platform_driver(imx_pwm_driver);
......
......@@ -176,8 +176,6 @@ static int lgm_pwm_probe(struct platform_device *pdev)
if (!pc)
return -ENOMEM;
platform_set_drvdata(pdev, pc);
io_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(io_base))
return PTR_ERR(io_base);
......@@ -210,20 +208,13 @@ static int lgm_pwm_probe(struct platform_device *pdev)
lgm_pwm_init(pc);
ret = pwmchip_add(&pc->chip);
ret = devm_pwmchip_add(dev, &pc->chip);
if (ret < 0)
return dev_err_probe(dev, ret, "failed to add PWM chip\n");
return 0;
}
static int lgm_pwm_remove(struct platform_device *pdev)
{
struct lgm_pwm_chip *pc = platform_get_drvdata(pdev);
return pwmchip_remove(&pc->chip);
}
static const struct of_device_id lgm_pwm_of_match[] = {
{ .compatible = "intel,lgm-pwm" },
{ }
......@@ -236,7 +227,6 @@ static struct platform_driver lgm_pwm_driver = {
.of_match_table = lgm_pwm_of_match,
},
.probe = lgm_pwm_probe,
.remove = lgm_pwm_remove,
};
module_platform_driver(lgm_pwm_driver);
......
......@@ -189,7 +189,6 @@ static int iqs620_pwm_probe(struct platform_device *pdev)
if (!iqs620_pwm)
return -ENOMEM;
platform_set_drvdata(pdev, iqs620_pwm);
iqs620_pwm->iqs62x = iqs62x;
ret = regmap_read(iqs62x->regmap, IQS620_PWR_SETTINGS, &val);
......@@ -224,31 +223,18 @@ static int iqs620_pwm_probe(struct platform_device *pdev)
if (ret)
return ret;
ret = pwmchip_add(&iqs620_pwm->chip);
ret = devm_pwmchip_add(&pdev->dev, &iqs620_pwm->chip);
if (ret)
dev_err(&pdev->dev, "Failed to add device: %d\n", ret);
return ret;
}
static int iqs620_pwm_remove(struct platform_device *pdev)
{
struct iqs620_pwm_private *iqs620_pwm = platform_get_drvdata(pdev);
int ret;
ret = pwmchip_remove(&iqs620_pwm->chip);
if (ret)
dev_err(&pdev->dev, "Failed to remove device: %d\n", ret);
return ret;
}
static struct platform_driver iqs620_pwm_platform_driver = {
.driver = {
.name = "iqs620a-pwm",
},
.probe = iqs620_pwm_probe,
.remove = iqs620_pwm_remove,
};
module_platform_driver(iqs620_pwm_platform_driver);
......
......@@ -245,16 +245,7 @@ static int jz4740_pwm_probe(struct platform_device *pdev)
jz4740->chip.ops = &jz4740_pwm_ops;
jz4740->chip.npwm = info->num_pwms;
platform_set_drvdata(pdev, jz4740);
return pwmchip_add(&jz4740->chip);
}
static int jz4740_pwm_remove(struct platform_device *pdev)
{
struct jz4740_pwm_chip *jz4740 = platform_get_drvdata(pdev);
return pwmchip_remove(&jz4740->chip);
return devm_pwmchip_add(dev, &jz4740->chip);
}
static const struct soc_info __maybe_unused jz4740_soc_info = {
......@@ -280,7 +271,6 @@ static struct platform_driver jz4740_pwm_driver = {
.of_match_table = of_match_ptr(jz4740_pwm_dt_ids),
},
.probe = jz4740_pwm_probe,
.remove = jz4740_pwm_remove,
};
module_platform_driver(jz4740_pwm_driver);
......
......@@ -207,22 +207,13 @@ static int keembay_pwm_probe(struct platform_device *pdev)
priv->chip.ops = &keembay_pwm_ops;
priv->chip.npwm = KMB_TOTAL_PWM_CHANNELS;
ret = pwmchip_add(&priv->chip);
ret = devm_pwmchip_add(dev, &priv->chip);
if (ret)
return dev_err_probe(dev, ret, "Failed to add PWM chip\n");
platform_set_drvdata(pdev, priv);
return 0;
}
static int keembay_pwm_remove(struct platform_device *pdev)
{
struct keembay_pwm *priv = platform_get_drvdata(pdev);
return pwmchip_remove(&priv->chip);
}
static const struct of_device_id keembay_pwm_of_match[] = {
{ .compatible = "intel,keembay-pwm" },
{ }
......@@ -231,7 +222,6 @@ MODULE_DEVICE_TABLE(of, keembay_pwm_of_match);
static struct platform_driver keembay_pwm_driver = {
.probe = keembay_pwm_probe,
.remove = keembay_pwm_remove,
.driver = {
.name = "pwm-keembay",
.of_match_table = keembay_pwm_of_match,
......
......@@ -276,16 +276,7 @@ static int lp3943_pwm_probe(struct platform_device *pdev)
lp3943_pwm->chip.ops = &lp3943_pwm_ops;
lp3943_pwm->chip.npwm = LP3943_NUM_PWMS;
platform_set_drvdata(pdev, lp3943_pwm);
return pwmchip_add(&lp3943_pwm->chip);
}
static int lp3943_pwm_remove(struct platform_device *pdev)
{
struct lp3943_pwm *lp3943_pwm = platform_get_drvdata(pdev);
return pwmchip_remove(&lp3943_pwm->chip);
return devm_pwmchip_add(&pdev->dev, &lp3943_pwm->chip);
}
#ifdef CONFIG_OF
......@@ -298,7 +289,6 @@ MODULE_DEVICE_TABLE(of, lp3943_pwm_of_match);
static struct platform_driver lp3943_pwm_driver = {
.probe = lp3943_pwm_probe,
.remove = lp3943_pwm_remove,
.driver = {
.name = "lp3943-pwm",
.of_match_table = of_match_ptr(lp3943_pwm_of_match),
......
......@@ -117,29 +117,20 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
lpc32xx->chip.ops = &lpc32xx_pwm_ops;
lpc32xx->chip.npwm = 1;
ret = pwmchip_add(&lpc32xx->chip);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add PWM chip, error %d\n", ret);
return ret;
}
/* When PWM is disable, configure the output to the default value */
/* If PWM is disabled, configure the output to the default value */
val = readl(lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2));
val &= ~PWM_PIN_LEVEL;
writel(val, lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2));
platform_set_drvdata(pdev, lpc32xx);
ret = devm_pwmchip_add(&pdev->dev, &lpc32xx->chip);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add PWM chip, error %d\n", ret);
return ret;
}
return 0;
}
static int lpc32xx_pwm_remove(struct platform_device *pdev)
{
struct lpc32xx_pwm_chip *lpc32xx = platform_get_drvdata(pdev);
return pwmchip_remove(&lpc32xx->chip);
}
static const struct of_device_id lpc32xx_pwm_dt_ids[] = {
{ .compatible = "nxp,lpc3220-pwm", },
{ /* sentinel */ }
......@@ -152,7 +143,6 @@ static struct platform_driver lpc32xx_pwm_driver = {
.of_match_table = lpc32xx_pwm_dt_ids,
},
.probe = lpc32xx_pwm_probe,
.remove = lpc32xx_pwm_remove,
};
module_platform_driver(lpc32xx_pwm_driver);
......
......@@ -253,13 +253,11 @@ static int pwm_mediatek_probe(struct platform_device *pdev)
}
}
platform_set_drvdata(pdev, pc);
pc->chip.dev = &pdev->dev;
pc->chip.ops = &pwm_mediatek_ops;
pc->chip.npwm = pc->soc->num_pwms;
ret = pwmchip_add(&pc->chip);
ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
if (ret < 0) {
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
return ret;
......@@ -268,13 +266,6 @@ static int pwm_mediatek_probe(struct platform_device *pdev)
return 0;
}
static int pwm_mediatek_remove(struct platform_device *pdev)
{
struct pwm_mediatek_chip *pc = platform_get_drvdata(pdev);
return pwmchip_remove(&pc->chip);
}
static const struct pwm_mediatek_of_data mt2712_pwm_data = {
.num_pwms = 8,
.pwm45_fixup = false,
......@@ -335,7 +326,6 @@ static struct platform_driver pwm_mediatek_driver = {
.of_match_table = pwm_mediatek_of_match,
},
.probe = pwm_mediatek_probe,
.remove = pwm_mediatek_remove,
};
module_platform_driver(pwm_mediatek_driver);
......
......@@ -5,6 +5,7 @@
* Author: YH Huang <yh.huang@mediatek.com>
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
......@@ -47,6 +48,7 @@ struct mtk_disp_pwm {
struct clk *clk_main;
struct clk *clk_mm;
void __iomem *base;
bool enabled;
};
static inline struct mtk_disp_pwm *to_mtk_disp_pwm(struct pwm_chip *chip)
......@@ -66,14 +68,47 @@ static void mtk_disp_pwm_update_bits(struct mtk_disp_pwm *mdp, u32 offset,
writel(value, address);
}
static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns)
static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
u32 clk_div, period, high_width, value;
u64 div, rate;
int err;
if (state->polarity != PWM_POLARITY_NORMAL)
return -EINVAL;
if (!state->enabled) {
mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
0x0);
if (mdp->enabled) {
clk_disable_unprepare(mdp->clk_mm);
clk_disable_unprepare(mdp->clk_main);
}
mdp->enabled = false;
return 0;
}
if (!mdp->enabled) {
err = clk_prepare_enable(mdp->clk_main);
if (err < 0) {
dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n",
ERR_PTR(err));
return err;
}
err = clk_prepare_enable(mdp->clk_mm);
if (err < 0) {
dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n",
ERR_PTR(err));
clk_disable_unprepare(mdp->clk_main);
return err;
}
}
/*
* Find period, high_width and clk_div to suit duty_ns and period_ns.
* Calculate proper div value to keep period value in the bound.
......@@ -85,29 +120,24 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
* high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1))
*/
rate = clk_get_rate(mdp->clk_main);
clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
clk_div = mul_u64_u64_div_u64(state->period, rate, NSEC_PER_SEC) >>
PWM_PERIOD_BIT_WIDTH;
if (clk_div > PWM_CLKDIV_MAX)
if (clk_div > PWM_CLKDIV_MAX) {
if (!mdp->enabled) {
clk_disable_unprepare(mdp->clk_mm);
clk_disable_unprepare(mdp->clk_main);
}
return -EINVAL;
}
div = NSEC_PER_SEC * (clk_div + 1);
period = div64_u64(rate * period_ns, div);
period = mul_u64_u64_div_u64(state->period, rate, div);
if (period > 0)
period--;
high_width = div64_u64(rate * duty_ns, div);
high_width = mul_u64_u64_div_u64(state->duty_cycle, rate, div);
value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
err = clk_enable(mdp->clk_main);
if (err < 0)
return err;
err = clk_enable(mdp->clk_mm);
if (err < 0) {
clk_disable(mdp->clk_main);
return err;
}
mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
PWM_CLKDIV_MASK,
clk_div << PWM_CLKDIV_SHIFT);
......@@ -122,50 +152,70 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
mdp->data->commit_mask,
0x0);
} else {
/*
* For MT2701, disable double buffer before writing register
* and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
*/
mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
mdp->data->bls_debug_mask,
mdp->data->bls_debug_mask);
mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
mdp->data->con0_sel,
mdp->data->con0_sel);
}
clk_disable(mdp->clk_mm);
clk_disable(mdp->clk_main);
mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
mdp->data->enable_mask);
mdp->enabled = true;
return 0;
}
static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
struct pwm_device *pwm,
struct pwm_state *state)
{
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
u64 rate, period, high_width;
u32 clk_div, con0, con1;
int err;
err = clk_enable(mdp->clk_main);
if (err < 0)
return err;
err = clk_enable(mdp->clk_mm);
err = clk_prepare_enable(mdp->clk_main);
if (err < 0) {
clk_disable(mdp->clk_main);
return err;
dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
return;
}
mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
mdp->data->enable_mask);
return 0;
}
static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
0x0);
err = clk_prepare_enable(mdp->clk_mm);
if (err < 0) {
dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
clk_disable_unprepare(mdp->clk_main);
return;
}
clk_disable(mdp->clk_mm);
clk_disable(mdp->clk_main);
rate = clk_get_rate(mdp->clk_main);
con0 = readl(mdp->base + mdp->data->con0);
con1 = readl(mdp->base + mdp->data->con1);
state->enabled = !!(con0 & BIT(0));
clk_div = FIELD_GET(PWM_CLKDIV_MASK, con0);
period = FIELD_GET(PWM_PERIOD_MASK, con1);
/*
* period has 12 bits, clk_div 11 and NSEC_PER_SEC has 30,
* so period * (clk_div + 1) * NSEC_PER_SEC doesn't overflow.
*/
state->period = DIV64_U64_ROUND_UP(period * (clk_div + 1) * NSEC_PER_SEC, rate);
high_width = FIELD_GET(PWM_HIGH_WIDTH_MASK, con1);
state->duty_cycle = DIV64_U64_ROUND_UP(high_width * (clk_div + 1) * NSEC_PER_SEC,
rate);
state->polarity = PWM_POLARITY_NORMAL;
clk_disable_unprepare(mdp->clk_mm);
clk_disable_unprepare(mdp->clk_main);
}
static const struct pwm_ops mtk_disp_pwm_ops = {
.config = mtk_disp_pwm_config,
.enable = mtk_disp_pwm_enable,
.disable = mtk_disp_pwm_disable,
.apply = mtk_disp_pwm_apply,
.get_state = mtk_disp_pwm_get_state,
.owner = THIS_MODULE,
};
......@@ -192,58 +242,28 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
if (IS_ERR(mdp->clk_mm))
return PTR_ERR(mdp->clk_mm);
ret = clk_prepare(mdp->clk_main);
if (ret < 0)
return ret;
ret = clk_prepare(mdp->clk_mm);
if (ret < 0)
goto disable_clk_main;
mdp->chip.dev = &pdev->dev;
mdp->chip.ops = &mtk_disp_pwm_ops;
mdp->chip.npwm = 1;
ret = pwmchip_add(&mdp->chip);
if (ret < 0) {
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
goto disable_clk_mm;
dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret));
return ret;
}
platform_set_drvdata(pdev, mdp);
/*
* For MT2701, disable double buffer before writing register
* and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
*/
if (!mdp->data->has_commit) {
mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
mdp->data->bls_debug_mask,
mdp->data->bls_debug_mask);
mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
mdp->data->con0_sel,
mdp->data->con0_sel);
}
return 0;
disable_clk_mm:
clk_unprepare(mdp->clk_mm);
disable_clk_main:
clk_unprepare(mdp->clk_main);
return ret;
}
static int mtk_disp_pwm_remove(struct platform_device *pdev)
{
struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
int ret;
ret = pwmchip_remove(&mdp->chip);
clk_unprepare(mdp->clk_mm);
clk_unprepare(mdp->clk_main);
pwmchip_remove(&mdp->chip);
return ret;
return 0;
}
static const struct mtk_pwm_data mt2701_pwm_data = {
......
......@@ -145,30 +145,18 @@ static int mxs_pwm_probe(struct platform_device *pdev)
return ret;
}
ret = pwmchip_add(&mxs->chip);
/* FIXME: Only do this if the PWM isn't already running */
ret = stmp_reset_block(mxs->base);
if (ret)
return dev_err_probe(&pdev->dev, ret, "failed to reset PWM\n");
ret = devm_pwmchip_add(&pdev->dev, &mxs->chip);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add pwm chip %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, mxs);
ret = stmp_reset_block(mxs->base);
if (ret)
goto pwm_remove;
return 0;
pwm_remove:
pwmchip_remove(&mxs->chip);
return ret;
}
static int mxs_pwm_remove(struct platform_device *pdev)
{
struct mxs_pwm_chip *mxs = platform_get_drvdata(pdev);
return pwmchip_remove(&mxs->chip);
}
static const struct of_device_id mxs_pwm_dt_ids[] = {
......@@ -183,7 +171,6 @@ static struct platform_driver mxs_pwm_driver = {
.of_match_table = mxs_pwm_dt_ids,
},
.probe = mxs_pwm_probe,
.remove = mxs_pwm_remove,
};
module_platform_driver(mxs_pwm_driver);
......
......@@ -150,23 +150,12 @@ static int ntxec_pwm_probe(struct platform_device *pdev)
priv->ec = ec;
priv->dev = &pdev->dev;
platform_set_drvdata(pdev, priv);
chip = &priv->chip;
chip->dev = &pdev->dev;
chip->ops = &ntxec_pwm_ops;
chip->base = -1;
chip->npwm = 1;
return pwmchip_add(chip);
}
static int ntxec_pwm_remove(struct platform_device *pdev)
{
struct ntxec_pwm *priv = platform_get_drvdata(pdev);
struct pwm_chip *chip = &priv->chip;
return pwmchip_remove(chip);
return devm_pwmchip_add(&pdev->dev, chip);
}
static struct platform_driver ntxec_pwm_driver = {
......@@ -174,7 +163,6 @@ static struct platform_driver ntxec_pwm_driver = {
.name = "ntxec-pwm",
},
.probe = ntxec_pwm_probe,
.remove = ntxec_pwm_remove,
};
module_platform_driver(ntxec_pwm_driver);
......
......@@ -444,11 +444,8 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
{
struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev);
int ret;
ret = pwmchip_remove(&omap->chip);
if (ret)
return ret;
pwmchip_remove(&omap->chip);
if (pm_runtime_active(&omap->dm_timer_pdev->dev))
omap->pdata->stop(omap->dm_timer);
......
......@@ -601,11 +601,8 @@ static int pca9685_pwm_probe(struct i2c_client *client,
static int pca9685_pwm_remove(struct i2c_client *client)
{
struct pca9685 *pca = i2c_get_clientdata(client);
int ret;
ret = pwmchip_remove(&pca->chip);
if (ret)
return ret;
pwmchip_remove(&pca->chip);
if (!pm_runtime_enabled(&client->dev)) {
/* Put chip in sleep state if runtime PM is disabled */
......
......@@ -195,32 +195,21 @@ static int pwm_probe(struct platform_device *pdev)
if (IS_ERR(pc->mmio_base))
return PTR_ERR(pc->mmio_base);
ret = pwmchip_add(&pc->chip);
ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
if (ret < 0) {
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, pc);
return 0;
}
static int pwm_remove(struct platform_device *pdev)
{
struct pxa_pwm_chip *pc;
pc = platform_get_drvdata(pdev);
return pwmchip_remove(&pc->chip);
}
static struct platform_driver pwm_driver = {
.driver = {
.name = "pxa25x-pwm",
.of_match_table = pwm_of_match,
},
.probe = pwm_probe,
.remove = pwm_remove,
.id_table = pwm_id_table,
};
......
......@@ -166,8 +166,6 @@ static int raspberrypi_pwm_probe(struct platform_device *pdev)
rpipwm->chip.base = -1;
rpipwm->chip.npwm = RASPBERRYPI_FIRMWARE_PWM_NUM;
platform_set_drvdata(pdev, rpipwm);
ret = raspberrypi_pwm_get_property(rpipwm->firmware, RPI_PWM_CUR_DUTY_REG,
&rpipwm->duty_cycle);
if (ret) {
......@@ -175,14 +173,7 @@ static int raspberrypi_pwm_probe(struct platform_device *pdev)
return ret;
}
return pwmchip_add(&rpipwm->chip);
}
static int raspberrypi_pwm_remove(struct platform_device *pdev)
{
struct raspberrypi_pwm *rpipwm = platform_get_drvdata(pdev);
return pwmchip_remove(&rpipwm->chip);
return devm_pwmchip_add(dev, &rpipwm->chip);
}
static const struct of_device_id raspberrypi_pwm_of_match[] = {
......@@ -197,7 +188,6 @@ static struct platform_driver raspberrypi_pwm_driver = {
.of_match_table = raspberrypi_pwm_of_match,
},
.probe = raspberrypi_pwm_probe,
.remove = raspberrypi_pwm_remove,
};
module_platform_driver(raspberrypi_pwm_driver);
......
......@@ -241,13 +241,12 @@ static int rcar_pwm_probe(struct platform_device *pdev)
static int rcar_pwm_remove(struct platform_device *pdev)
{
struct rcar_pwm_chip *rcar_pwm = platform_get_drvdata(pdev);
int ret;
ret = pwmchip_remove(&rcar_pwm->chip);
pwmchip_remove(&rcar_pwm->chip);
pm_runtime_disable(&pdev->dev);
return ret;
return 0;
}
static const struct of_device_id rcar_pwm_of_table[] = {
......
......@@ -425,13 +425,12 @@ static int tpu_probe(struct platform_device *pdev)
static int tpu_remove(struct platform_device *pdev)
{
struct tpu_device *tpu = platform_get_drvdata(pdev);
int ret;
ret = pwmchip_remove(&tpu->chip);
pwmchip_remove(&tpu->chip);
pm_runtime_disable(&pdev->dev);
return ret;
return 0;
}
#ifdef CONFIG_OF
......
......@@ -384,24 +384,12 @@ static int rockchip_pwm_remove(struct platform_device *pdev)
{
struct rockchip_pwm_chip *pc = platform_get_drvdata(pdev);
/*
* Disable the PWM clk before unpreparing it if the PWM device is still
* running. This should only happen when the last PWM user left it
* enabled, or when nobody requested a PWM that was previously enabled
* by the bootloader.
*
* FIXME: Maybe the core should disable all PWM devices in
* pwmchip_remove(). In this case we'd only have to call
* clk_unprepare() after pwmchip_remove().
*
*/
if (pwm_is_enabled(pc->chip.pwms))
clk_disable(pc->clk);
pwmchip_remove(&pc->chip);
clk_unprepare(pc->pclk);
clk_unprepare(pc->clk);
return pwmchip_remove(&pc->chip);
return 0;
}
static struct platform_driver rockchip_pwm_driver = {
......
......@@ -580,11 +580,8 @@ static int pwm_samsung_probe(struct platform_device *pdev)
static int pwm_samsung_remove(struct platform_device *pdev)
{
struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
int ret;
ret = pwmchip_remove(&chip->chip);
if (ret < 0)
return ret;
pwmchip_remove(&chip->chip);
clk_disable_unprepare(chip->base_clk);
......
......@@ -291,7 +291,7 @@ static int pwm_sifive_remove(struct platform_device *dev)
struct pwm_sifive_ddata *ddata = platform_get_drvdata(dev);
bool is_enabled = false;
struct pwm_device *pwm;
int ret, ch;
int ch;
for (ch = 0; ch < ddata->chip.npwm; ch++) {
pwm = &ddata->chip.pwms[ch];
......@@ -304,10 +304,10 @@ static int pwm_sifive_remove(struct platform_device *dev)
clk_disable(ddata->clk);
clk_disable_unprepare(ddata->clk);
ret = pwmchip_remove(&ddata->chip);
pwmchip_remove(&ddata->chip);
clk_notifier_unregister(ddata->clk, &ddata->notifier);
return ret;
return 0;
}
static const struct of_device_id pwm_sifive_of_match[] = {
......
......@@ -231,9 +231,7 @@ static int sl28cpld_pwm_probe(struct platform_device *pdev)
chip->ops = &sl28cpld_pwm_ops;
chip->npwm = 1;
platform_set_drvdata(pdev, priv);
ret = pwmchip_add(&priv->pwm_chip);
ret = devm_pwmchip_add(&pdev->dev, &priv->pwm_chip);
if (ret) {
dev_err(&pdev->dev, "failed to add PWM chip (%pe)",
ERR_PTR(ret));
......@@ -243,13 +241,6 @@ static int sl28cpld_pwm_probe(struct platform_device *pdev)
return 0;
}
static int sl28cpld_pwm_remove(struct platform_device *pdev)
{
struct sl28cpld_pwm *priv = platform_get_drvdata(pdev);
return pwmchip_remove(&priv->pwm_chip);
}
static const struct of_device_id sl28cpld_pwm_of_match[] = {
{ .compatible = "kontron,sl28cpld-pwm" },
{}
......@@ -258,7 +249,6 @@ MODULE_DEVICE_TABLE(of, sl28cpld_pwm_of_match);
static struct platform_driver sl28cpld_pwm_driver = {
.probe = sl28cpld_pwm_probe,
.remove = sl28cpld_pwm_remove,
.driver = {
.name = "sl28cpld-pwm",
.of_match_table = sl28cpld_pwm_of_match,
......
......@@ -209,7 +209,7 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev)
priv->chip.ops = &stm32_pwm_lp_ops;
priv->chip.npwm = 1;
ret = pwmchip_add(&priv->chip);
ret = devm_pwmchip_add(&pdev->dev, &priv->chip);
if (ret < 0)
return ret;
......@@ -218,15 +218,6 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev)
return 0;
}
static int stm32_pwm_lp_remove(struct platform_device *pdev)
{
struct stm32_pwm_lp *priv = platform_get_drvdata(pdev);
pwm_disable(&priv->chip.pwms[0]);
return pwmchip_remove(&priv->chip);
}
static int __maybe_unused stm32_pwm_lp_suspend(struct device *dev)
{
struct stm32_pwm_lp *priv = dev_get_drvdata(dev);
......@@ -258,7 +249,6 @@ MODULE_DEVICE_TABLE(of, stm32_pwm_lp_of_match);
static struct platform_driver stm32_pwm_lp_driver = {
.probe = stm32_pwm_lp_probe,
.remove = stm32_pwm_lp_remove,
.driver = {
.name = "stm32-pwm-lp",
.of_match_table = of_match_ptr(stm32_pwm_lp_of_match),
......
......@@ -484,11 +484,8 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
static int sun4i_pwm_remove(struct platform_device *pdev)
{
struct sun4i_pwm_chip *pwm = platform_get_drvdata(pdev);
int ret;
ret = pwmchip_remove(&pwm->chip);
if (ret)
return ret;
pwmchip_remove(&pwm->chip);
clk_disable_unprepare(pwm->bus_clk);
reset_control_assert(pwm->rst);
......
......@@ -253,7 +253,7 @@ static int ecap_pwm_probe(struct platform_device *pdev)
if (IS_ERR(pc->mmio_base))
return PTR_ERR(pc->mmio_base);
ret = pwmchip_add(&pc->chip);
ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
if (ret < 0) {
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
return ret;
......@@ -267,11 +267,9 @@ static int ecap_pwm_probe(struct platform_device *pdev)
static int ecap_pwm_remove(struct platform_device *pdev)
{
struct ecap_pwm_chip *pc = platform_get_drvdata(pdev);
pm_runtime_disable(&pdev->dev);
return pwmchip_remove(&pc->chip);
return 0;
}
#ifdef CONFIG_PM_SLEEP
......
......@@ -485,11 +485,13 @@ static int ehrpwm_pwm_remove(struct platform_device *pdev)
{
struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev);
pwmchip_remove(&pc->chip);
clk_unprepare(pc->tbclk);
pm_runtime_disable(&pdev->dev);
return pwmchip_remove(&pc->chip);
return 0;
}
#ifdef CONFIG_PM_SLEEP
......
......@@ -276,7 +276,6 @@ static const struct pwm_ops twl6030_pwmled_ops = {
static int twl_pwmled_probe(struct platform_device *pdev)
{
struct twl_pwmled_chip *twl;
int ret;
twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL);
if (!twl)
......@@ -294,20 +293,7 @@ static int twl_pwmled_probe(struct platform_device *pdev)
mutex_init(&twl->mutex);
ret = pwmchip_add(&twl->chip);
if (ret < 0)
return ret;
platform_set_drvdata(pdev, twl);
return 0;
}
static int twl_pwmled_remove(struct platform_device *pdev)
{
struct twl_pwmled_chip *twl = platform_get_drvdata(pdev);
return pwmchip_remove(&twl->chip);
return devm_pwmchip_add(&pdev->dev, &twl->chip);
}
#ifdef CONFIG_OF
......@@ -325,7 +311,6 @@ static struct platform_driver twl_pwmled_driver = {
.of_match_table = of_match_ptr(twl_pwmled_of_match),
},
.probe = twl_pwmled_probe,
.remove = twl_pwmled_remove,
};
module_platform_driver(twl_pwmled_driver);
......
......@@ -298,7 +298,6 @@ static const struct pwm_ops twl6030_pwm_ops = {
static int twl_pwm_probe(struct platform_device *pdev)
{
struct twl_pwm_chip *twl;
int ret;
twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL);
if (!twl)
......@@ -314,20 +313,7 @@ static int twl_pwm_probe(struct platform_device *pdev)
mutex_init(&twl->mutex);
ret = pwmchip_add(&twl->chip);
if (ret < 0)
return ret;
platform_set_drvdata(pdev, twl);
return 0;
}
static int twl_pwm_remove(struct platform_device *pdev)
{
struct twl_pwm_chip *twl = platform_get_drvdata(pdev);
return pwmchip_remove(&twl->chip);
return devm_pwmchip_add(&pdev->dev, &twl->chip);
}
#ifdef CONFIG_OF
......@@ -345,7 +331,6 @@ static struct platform_driver twl_pwm_driver = {
.of_match_table = of_match_ptr(twl_pwm_of_match),
},
.probe = twl_pwm_probe,
.remove = twl_pwm_remove,
};
module_platform_driver(twl_pwm_driver);
......
......@@ -404,7 +404,7 @@ int pwm_set_chip_data(struct pwm_device *pwm, void *data);
void *pwm_get_chip_data(struct pwm_device *pwm);
int pwmchip_add(struct pwm_chip *chip);
int pwmchip_remove(struct pwm_chip *chip);
void pwmchip_remove(struct pwm_chip *chip);
int devm_pwmchip_add(struct device *dev, struct pwm_chip *chip);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment