mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
pwm: Changes for v5.16-rc1
This set is mostly small fixes and cleanups, so more of a janitorial update for this cycle. -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEEiOrDCAFJzPfAjcif3SOs138+s6EFAmGOQhEZHHRoaWVycnku cmVkaW5nQGdtYWlsLmNvbQAKCRDdI6zXfz6zoaQGD/9CHCzKlhFn60fE1BI7FADK tLIe4LdnjLju06CrCRE4jZVyJdHlo2iNUCTvsBv6BwrqyNrxGP33ZoCzJpmvGI69 aiBFhm4bJeUe8USUosXsgPaXPuzjQ+G3WMZmGdHs8zgCxw2Kpve5f3JXgpmgtYfM uRGZDpYZxboeO2rx8xnyhhMk8BJ4rMAJInMu7pRhnV93MLPIieui0xbVRkboNxG+ FAElquk6eN2LlLYoSeFUqx7Na3GI+SGdfCkqX8SLe4AymD2Dm4Aj0+CsqM+Rwlff w8TRO0bMXN5yrnol1ARD9TlNsmh/tTRDGSq0amxiXaPHPfCSPCAQHu274tAdQqOP LVNxkm/JJFeanz3FJJot4saOwnTyRnOOXHxtbmze1kiZNDqs2fJhffKTJNptQoGm QPn5PC0hLQhMMNJ5l+ENWAMVpRCtU4w5B28fmQyo3Np4VLbZcz20RAxl55O0roIv NIDMVmIyDyxa2+VUOVEmeuRsGcAzGQwYpwjVzf2vmWxc1CMxmKw35TcSYvWIAwRp LY/xeStEkNeGWf4YfsDeWIeUjveVDXzkMHbfrnQxt0gK3TLdvf3qoB6elFjd8EN+ unvfulvQ5RU4dXef0zduJAQQ4HMXbJvbaq8cZhZYxyPA0o9pZJcILxCXOdHqjSw9 q+uk+I7CtDOCZVqy0REAAA== =KmUV -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
030c28a021
@ -35,9 +35,11 @@ properties:
|
||||
- renesas,tpu-r8a7794 # R-Car E2
|
||||
- renesas,tpu-r8a7795 # R-Car H3
|
||||
- renesas,tpu-r8a7796 # R-Car M3-W
|
||||
- renesas,tpu-r8a77961 # R-Car M3-W+
|
||||
- renesas,tpu-r8a77965 # R-Car M3-N
|
||||
- renesas,tpu-r8a77970 # R-Car V3M
|
||||
- renesas,tpu-r8a77980 # R-Car V3H
|
||||
- renesas,tpu-r8a779a0 # R-Car V3U
|
||||
- const: renesas,tpu
|
||||
|
||||
reg:
|
||||
|
@ -476,7 +476,9 @@ config PWM_SAMSUNG
|
||||
depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
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
|
||||
will be called pwm-samsung.
|
||||
|
@ -532,6 +532,15 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
|
||||
struct pwm_chip *chip;
|
||||
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 ||
|
||||
state->duty_cycle > state->period)
|
||||
return -EINVAL;
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -117,6 +117,20 @@ static inline unsigned int to_tcon_channel(unsigned int channel)
|
||||
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,
|
||||
unsigned int channel, u8 divisor)
|
||||
{
|
||||
@ -276,6 +290,13 @@ static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
tcon &= ~TCON_AUTORELOAD(tcon_chan);
|
||||
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);
|
||||
|
||||
spin_unlock_irqrestore(&samsung_pwm_lock, flags);
|
||||
@ -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,
|
||||
struct pwm_device *pwm)
|
||||
{
|
||||
unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
|
||||
u32 tcon;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&samsung_pwm_lock, flags);
|
||||
|
||||
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);
|
||||
__pwm_samsung_manual_update(chip, pwm);
|
||||
|
||||
spin_unlock_irqrestore(&samsung_pwm_lock, flags);
|
||||
}
|
||||
|
@ -144,28 +144,17 @@ static int visconti_pwm_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(priv->base))
|
||||
return PTR_ERR(priv->base);
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
priv->chip.dev = dev;
|
||||
priv->chip.ops = &visconti_pwm_ops;
|
||||
priv->chip.npwm = 4;
|
||||
|
||||
ret = pwmchip_add(&priv->chip);
|
||||
ret = devm_pwmchip_add(&pdev->dev, &priv->chip);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret, "Cannot register visconti PWM\n");
|
||||
|
||||
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[] = {
|
||||
{ .compatible = "toshiba,visconti-pwm", },
|
||||
{ }
|
||||
@ -178,7 +167,6 @@ static struct platform_driver visconti_pwm_driver = {
|
||||
.of_match_table = visconti_pwm_of_match,
|
||||
},
|
||||
.probe = visconti_pwm_probe,
|
||||
.remove = visconti_pwm_remove,
|
||||
};
|
||||
module_platform_driver(visconti_pwm_driver);
|
||||
|
||||
|
@ -56,7 +56,7 @@ struct vt8500_chip {
|
||||
#define to_vt8500_chip(chip) container_of(chip, struct vt8500_chip, chip)
|
||||
|
||||
#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);
|
||||
u32 mask = bitmask << (nr << 8);
|
||||
@ -106,18 +106,18 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
dc = c;
|
||||
|
||||
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));
|
||||
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));
|
||||
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 |= CTRL_AUTOLOAD;
|
||||
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);
|
||||
return 0;
|
||||
@ -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 |= CTRL_ENABLE;
|
||||
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;
|
||||
}
|
||||
@ -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 &= ~CTRL_ENABLE;
|
||||
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);
|
||||
}
|
||||
@ -171,7 +171,7 @@ static int vt8500_pwm_set_polarity(struct pwm_chip *chip,
|
||||
val &= ~CTRL_INVERT;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -429,16 +429,19 @@ struct pwm_device *devm_fwnode_pwm_get(struct device *dev,
|
||||
#else
|
||||
static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
|
||||
{
|
||||
might_sleep();
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static inline void pwm_free(struct pwm_device *pwm)
|
||||
{
|
||||
might_sleep();
|
||||
}
|
||||
|
||||
static inline int pwm_apply_state(struct pwm_device *pwm,
|
||||
const struct pwm_state *state)
|
||||
{
|
||||
might_sleep();
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
int period_ns)
|
||||
{
|
||||
might_sleep();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -462,11 +466,13 @@ static inline int pwm_capture(struct pwm_device *pwm,
|
||||
|
||||
static inline int pwm_enable(struct pwm_device *pwm)
|
||||
{
|
||||
might_sleep();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline void pwm_disable(struct pwm_device *pwm)
|
||||
{
|
||||
might_sleep();
|
||||
}
|
||||
|
||||
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,
|
||||
unsigned int index,
|
||||
const char *label)
|
||||
{
|
||||
might_sleep();
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static inline struct pwm_device *pwm_get(struct device *dev,
|
||||
const char *consumer)
|
||||
{
|
||||
might_sleep();
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
@ -506,16 +514,19 @@ static inline struct pwm_device *of_pwm_get(struct device *dev,
|
||||
struct device_node *np,
|
||||
const char *con_id)
|
||||
{
|
||||
might_sleep();
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static inline void pwm_put(struct pwm_device *pwm)
|
||||
{
|
||||
might_sleep();
|
||||
}
|
||||
|
||||
static inline struct pwm_device *devm_pwm_get(struct device *dev,
|
||||
const char *consumer)
|
||||
{
|
||||
might_sleep();
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
@ -523,6 +534,7 @@ static inline struct pwm_device *devm_of_pwm_get(struct device *dev,
|
||||
struct device_node *np,
|
||||
const char *con_id)
|
||||
{
|
||||
might_sleep();
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
@ -530,6 +542,7 @@ static inline struct pwm_device *
|
||||
devm_fwnode_pwm_get(struct device *dev, struct fwnode_handle *fwnode,
|
||||
const char *con_id)
|
||||
{
|
||||
might_sleep();
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user