Commit 030c28a0 authored by Linus Torvalds's avatar Linus Torvalds

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

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

Pull pwm updates from Thierry Reding:
 "This set is mostly small fixes and cleanups, so more of a janitorial
  update for this cycle"

* tag 'pwm/for-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
  pwm: vt8500: Rename pwm_busy_wait() to make it obviously driver-specific
  dt-bindings: pwm: tpu: Add R-Car M3-W+ device tree bindings
  dt-bindings: pwm: tpu: Add R-Car V3U device tree bindings
  pwm: pwm-samsung: Trigger manual update when disabling PWM
  pwm: visconti: Simplify using devm_pwmchip_add()
  pwm: samsung: Describe driver in Kconfig
  pwm: Make it explicit that pwm_apply_state() might sleep
  pwm: Add might_sleep() annotations for !CONFIG_PWM API functions
  pwm: atmel: Drop unused header
parents 0d5d7463 e9d866d5
...@@ -35,9 +35,11 @@ properties: ...@@ -35,9 +35,11 @@ properties:
- renesas,tpu-r8a7794 # R-Car E2 - renesas,tpu-r8a7794 # R-Car E2
- renesas,tpu-r8a7795 # R-Car H3 - renesas,tpu-r8a7795 # R-Car H3
- renesas,tpu-r8a7796 # R-Car M3-W - renesas,tpu-r8a7796 # R-Car M3-W
- renesas,tpu-r8a77961 # R-Car M3-W+
- renesas,tpu-r8a77965 # R-Car M3-N - renesas,tpu-r8a77965 # R-Car M3-N
- renesas,tpu-r8a77970 # R-Car V3M - renesas,tpu-r8a77970 # R-Car V3M
- renesas,tpu-r8a77980 # R-Car V3H - renesas,tpu-r8a77980 # R-Car V3H
- renesas,tpu-r8a779a0 # R-Car V3U
- const: renesas,tpu - const: renesas,tpu
reg: reg:
......
...@@ -476,7 +476,9 @@ config PWM_SAMSUNG ...@@ -476,7 +476,9 @@ config PWM_SAMSUNG
depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
help help
Generic PWM framework driver for Samsung. Generic PWM framework driver for Samsung S3C24xx, S3C64xx, S5Pv210
and Exynos SoCs.
Choose Y here only if you build for such Samsung SoC.
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called pwm-samsung. will be called pwm-samsung.
......
...@@ -532,6 +532,15 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state) ...@@ -532,6 +532,15 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
struct pwm_chip *chip; struct pwm_chip *chip;
int err; int err;
/*
* Some lowlevel driver's implementations of .apply() make use of
* mutexes, also with some drivers only returning when the new
* configuration is active calling pwm_apply_state() from atomic context
* is a bad idea. So make it explicit that calling this function might
* sleep.
*/
might_sleep();
if (!pwm || !state || !state->period || if (!pwm || !state || !state->period ||
state->duty_cycle > state->period) state->duty_cycle > state->period)
return -EINVAL; return -EINVAL;
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
......
...@@ -117,6 +117,20 @@ static inline unsigned int to_tcon_channel(unsigned int channel) ...@@ -117,6 +117,20 @@ static inline unsigned int to_tcon_channel(unsigned int channel)
return (channel == 0) ? 0 : (channel + 1); return (channel == 0) ? 0 : (channel + 1);
} }
static void __pwm_samsung_manual_update(struct samsung_pwm_chip *chip,
struct pwm_device *pwm)
{
unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
u32 tcon;
tcon = readl(chip->base + REG_TCON);
tcon |= TCON_MANUALUPDATE(tcon_chan);
writel(tcon, chip->base + REG_TCON);
tcon &= ~TCON_MANUALUPDATE(tcon_chan);
writel(tcon, chip->base + REG_TCON);
}
static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm, static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm,
unsigned int channel, u8 divisor) unsigned int channel, u8 divisor)
{ {
...@@ -276,6 +290,13 @@ static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm) ...@@ -276,6 +290,13 @@ static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
tcon &= ~TCON_AUTORELOAD(tcon_chan); tcon &= ~TCON_AUTORELOAD(tcon_chan);
writel(tcon, our_chip->base + REG_TCON); writel(tcon, our_chip->base + REG_TCON);
/*
* In case the PWM is at 100% duty cycle, force a manual
* update to prevent the signal from staying high.
*/
if (readl(our_chip->base + REG_TCMPB(pwm->hwpwm)) == (u32)-1U)
__pwm_samsung_manual_update(our_chip, pwm);
our_chip->disabled_mask |= BIT(pwm->hwpwm); our_chip->disabled_mask |= BIT(pwm->hwpwm);
spin_unlock_irqrestore(&samsung_pwm_lock, flags); spin_unlock_irqrestore(&samsung_pwm_lock, flags);
...@@ -284,18 +305,11 @@ static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm) ...@@ -284,18 +305,11 @@ static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
static void pwm_samsung_manual_update(struct samsung_pwm_chip *chip, static void pwm_samsung_manual_update(struct samsung_pwm_chip *chip,
struct pwm_device *pwm) struct pwm_device *pwm)
{ {
unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
u32 tcon;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&samsung_pwm_lock, flags); spin_lock_irqsave(&samsung_pwm_lock, flags);
tcon = readl(chip->base + REG_TCON); __pwm_samsung_manual_update(chip, pwm);
tcon |= TCON_MANUALUPDATE(tcon_chan);
writel(tcon, chip->base + REG_TCON);
tcon &= ~TCON_MANUALUPDATE(tcon_chan);
writel(tcon, chip->base + REG_TCON);
spin_unlock_irqrestore(&samsung_pwm_lock, flags); spin_unlock_irqrestore(&samsung_pwm_lock, flags);
} }
......
...@@ -144,28 +144,17 @@ static int visconti_pwm_probe(struct platform_device *pdev) ...@@ -144,28 +144,17 @@ static int visconti_pwm_probe(struct platform_device *pdev)
if (IS_ERR(priv->base)) if (IS_ERR(priv->base))
return PTR_ERR(priv->base); return PTR_ERR(priv->base);
platform_set_drvdata(pdev, priv);
priv->chip.dev = dev; priv->chip.dev = dev;
priv->chip.ops = &visconti_pwm_ops; priv->chip.ops = &visconti_pwm_ops;
priv->chip.npwm = 4; priv->chip.npwm = 4;
ret = pwmchip_add(&priv->chip); ret = devm_pwmchip_add(&pdev->dev, &priv->chip);
if (ret < 0) if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "Cannot register visconti PWM\n"); return dev_err_probe(&pdev->dev, ret, "Cannot register visconti PWM\n");
return 0; return 0;
} }
static int visconti_pwm_remove(struct platform_device *pdev)
{
struct visconti_pwm_chip *priv = platform_get_drvdata(pdev);
pwmchip_remove(&priv->chip);
return 0;
}
static const struct of_device_id visconti_pwm_of_match[] = { static const struct of_device_id visconti_pwm_of_match[] = {
{ .compatible = "toshiba,visconti-pwm", }, { .compatible = "toshiba,visconti-pwm", },
{ } { }
...@@ -178,7 +167,6 @@ static struct platform_driver visconti_pwm_driver = { ...@@ -178,7 +167,6 @@ static struct platform_driver visconti_pwm_driver = {
.of_match_table = visconti_pwm_of_match, .of_match_table = visconti_pwm_of_match,
}, },
.probe = visconti_pwm_probe, .probe = visconti_pwm_probe,
.remove = visconti_pwm_remove,
}; };
module_platform_driver(visconti_pwm_driver); module_platform_driver(visconti_pwm_driver);
......
...@@ -56,7 +56,7 @@ struct vt8500_chip { ...@@ -56,7 +56,7 @@ struct vt8500_chip {
#define to_vt8500_chip(chip) container_of(chip, struct vt8500_chip, chip) #define to_vt8500_chip(chip) container_of(chip, struct vt8500_chip, chip)
#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
static inline void pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 bitmask) static inline void vt8500_pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 bitmask)
{ {
int loops = msecs_to_loops(10); int loops = msecs_to_loops(10);
u32 mask = bitmask << (nr << 8); u32 mask = bitmask << (nr << 8);
...@@ -106,18 +106,18 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -106,18 +106,18 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
dc = c; dc = c;
writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm)); writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm));
pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE); vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE);
writel(pv, vt8500->base + REG_PERIOD(pwm->hwpwm)); writel(pv, vt8500->base + REG_PERIOD(pwm->hwpwm));
pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_PERIOD_UPDATE); vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_PERIOD_UPDATE);
writel(dc, vt8500->base + REG_DUTY(pwm->hwpwm)); writel(dc, vt8500->base + REG_DUTY(pwm->hwpwm));
pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_DUTY_UPDATE); vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_DUTY_UPDATE);
val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); val = readl(vt8500->base + REG_CTRL(pwm->hwpwm));
val |= CTRL_AUTOLOAD; val |= CTRL_AUTOLOAD;
writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
clk_disable(vt8500->clk); clk_disable(vt8500->clk);
return 0; return 0;
...@@ -138,7 +138,7 @@ static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ...@@ -138,7 +138,7 @@ static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); val = readl(vt8500->base + REG_CTRL(pwm->hwpwm));
val |= CTRL_ENABLE; val |= CTRL_ENABLE;
writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
return 0; return 0;
} }
...@@ -151,7 +151,7 @@ static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ...@@ -151,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 = readl(vt8500->base + REG_CTRL(pwm->hwpwm));
val &= ~CTRL_ENABLE; val &= ~CTRL_ENABLE;
writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
clk_disable(vt8500->clk); clk_disable(vt8500->clk);
} }
...@@ -171,7 +171,7 @@ static int vt8500_pwm_set_polarity(struct pwm_chip *chip, ...@@ -171,7 +171,7 @@ static int vt8500_pwm_set_polarity(struct pwm_chip *chip,
val &= ~CTRL_INVERT; val &= ~CTRL_INVERT;
writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
return 0; return 0;
} }
......
...@@ -429,16 +429,19 @@ struct pwm_device *devm_fwnode_pwm_get(struct device *dev, ...@@ -429,16 +429,19 @@ struct pwm_device *devm_fwnode_pwm_get(struct device *dev,
#else #else
static inline struct pwm_device *pwm_request(int pwm_id, const char *label) static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
{ {
might_sleep();
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
static inline void pwm_free(struct pwm_device *pwm) static inline void pwm_free(struct pwm_device *pwm)
{ {
might_sleep();
} }
static inline int pwm_apply_state(struct pwm_device *pwm, static inline int pwm_apply_state(struct pwm_device *pwm,
const struct pwm_state *state) const struct pwm_state *state)
{ {
might_sleep();
return -ENOTSUPP; return -ENOTSUPP;
} }
...@@ -450,6 +453,7 @@ static inline int pwm_adjust_config(struct pwm_device *pwm) ...@@ -450,6 +453,7 @@ static inline int pwm_adjust_config(struct pwm_device *pwm)
static inline int pwm_config(struct pwm_device *pwm, int duty_ns, static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
int period_ns) int period_ns)
{ {
might_sleep();
return -EINVAL; return -EINVAL;
} }
...@@ -462,11 +466,13 @@ static inline int pwm_capture(struct pwm_device *pwm, ...@@ -462,11 +466,13 @@ static inline int pwm_capture(struct pwm_device *pwm,
static inline int pwm_enable(struct pwm_device *pwm) static inline int pwm_enable(struct pwm_device *pwm)
{ {
might_sleep();
return -EINVAL; return -EINVAL;
} }
static inline void pwm_disable(struct pwm_device *pwm) static inline void pwm_disable(struct pwm_device *pwm)
{ {
might_sleep();
} }
static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data) static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
...@@ -493,12 +499,14 @@ static inline struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, ...@@ -493,12 +499,14 @@ static inline struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
unsigned int index, unsigned int index,
const char *label) const char *label)
{ {
might_sleep();
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
static inline struct pwm_device *pwm_get(struct device *dev, static inline struct pwm_device *pwm_get(struct device *dev,
const char *consumer) const char *consumer)
{ {
might_sleep();
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
...@@ -506,16 +514,19 @@ static inline struct pwm_device *of_pwm_get(struct device *dev, ...@@ -506,16 +514,19 @@ static inline struct pwm_device *of_pwm_get(struct device *dev,
struct device_node *np, struct device_node *np,
const char *con_id) const char *con_id)
{ {
might_sleep();
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
static inline void pwm_put(struct pwm_device *pwm) static inline void pwm_put(struct pwm_device *pwm)
{ {
might_sleep();
} }
static inline struct pwm_device *devm_pwm_get(struct device *dev, static inline struct pwm_device *devm_pwm_get(struct device *dev,
const char *consumer) const char *consumer)
{ {
might_sleep();
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
...@@ -523,6 +534,7 @@ static inline struct pwm_device *devm_of_pwm_get(struct device *dev, ...@@ -523,6 +534,7 @@ static inline struct pwm_device *devm_of_pwm_get(struct device *dev,
struct device_node *np, struct device_node *np,
const char *con_id) const char *con_id)
{ {
might_sleep();
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
...@@ -530,6 +542,7 @@ static inline struct pwm_device * ...@@ -530,6 +542,7 @@ static inline struct pwm_device *
devm_fwnode_pwm_get(struct device *dev, struct fwnode_handle *fwnode, devm_fwnode_pwm_get(struct device *dev, struct fwnode_handle *fwnode,
const char *con_id) const char *con_id)
{ {
might_sleep();
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
#endif #endif
......
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