Merge tag 'pwm/for-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Aug 2020 23:00:09 +0000 (16:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Aug 2020 23:00:09 +0000 (16:00 -0700)
Pull pwm updates from Thierry Reding:
 "The majority of this batch is conversion of the PWM period and duty
  cycle to 64-bit unsigned integers, which is required so that some
  types of hardware can generate the full range of signals that they're
  capable of.

  The remainder is mostly minor fixes and cleanups"

* tag 'pwm/for-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
  pwm: bcm-iproc: handle clk_get_rate() return
  pwm: Replace HTTP links with HTTPS ones
  pwm: omap-dmtimer: Repair pwm_omap_dmtimer_chip's broken kerneldoc header
  pwm: mediatek: Provide missing kerneldoc description for 'soc' arg
  pwm: bcm-kona: Remove impossible comparison when validating duty cycle
  pwm: bcm-iproc: Remove impossible comparison when validating duty cycle
  pwm: iqs620a: Use lowercase hexadecimal literals for consistency
  pwm: Convert period and duty cycle to u64
  clk: pwm: Use 64-bit division function
  backlight: pwm_bl: Use 64-bit division function
  pwm: sun4i: Use nsecs_to_jiffies to avoid a division
  pwm: sifive: Use 64-bit division macro
  pwm: iqs620a: Use 64-bit division
  pwm: imx27: Use 64-bit division macro
  pwm: imx-tpm: Use 64-bit division macro
  pwm: clps711x: Use 64-bit division macro
  hwmon: pwm-fan: Use 64-bit division macro
  drm/i915: Use 64-bit division macro

21 files changed:
drivers/clk/clk-pwm.c
drivers/gpu/drm/i915/display/intel_panel.c
drivers/hwmon/pwm-fan.c
drivers/pwm/core.c
drivers/pwm/pwm-bcm-iproc.c
drivers/pwm/pwm-bcm-kona.c
drivers/pwm/pwm-clps711x.c
drivers/pwm/pwm-imx-tpm.c
drivers/pwm/pwm-imx27.c
drivers/pwm/pwm-iqs620a.c
drivers/pwm/pwm-mediatek.c
drivers/pwm/pwm-omap-dmtimer.c
drivers/pwm/pwm-sifive.c
drivers/pwm/pwm-stm32-lp.c
drivers/pwm/pwm-sun4i.c
drivers/pwm/pwm-tiecap.c
drivers/pwm/pwm-tiehrpwm.c
drivers/pwm/sysfs.c
drivers/video/backlight/pwm_bl.c
drivers/video/fbdev/ssd1307fb.c
include/linux/pwm.h

index 87fe0b0e01a3d6ef980ea32ceea02d44a90cb2f7..86f2e2d3fc022dedaf965cb6a7fb5cfa030cc026 100644 (file)
@@ -89,7 +89,12 @@ static int clk_pwm_probe(struct platform_device *pdev)
        }
 
        if (of_property_read_u32(node, "clock-frequency", &clk_pwm->fixed_rate))
-               clk_pwm->fixed_rate = NSEC_PER_SEC / pargs.period;
+               clk_pwm->fixed_rate = div64_u64(NSEC_PER_SEC, pargs.period);
+
+       if (!clk_pwm->fixed_rate) {
+               dev_err(&pdev->dev, "fixed_rate cannot be zero\n");
+               return -EINVAL;
+       }
 
        if (pargs.period != NSEC_PER_SEC / clk_pwm->fixed_rate &&
            pargs.period != DIV_ROUND_UP(NSEC_PER_SEC, clk_pwm->fixed_rate)) {
index aaed9eb3b56cec206ef05cead5cdd2eb58eb718d..bbde3b12c3113cc83885bdc18851bbe0fba5979d 100644 (file)
@@ -1929,7 +1929,7 @@ static int pwm_setup_backlight(struct intel_connector *connector,
                return retval;
        }
 
-       level = DIV_ROUND_UP(pwm_get_duty_cycle(panel->backlight.pwm) * 100,
+       level = DIV_ROUND_UP_ULL(pwm_get_duty_cycle(panel->backlight.pwm) * 100,
                             CRC_PMIC_PWM_PERIOD_NS);
        panel->backlight.level =
                intel_panel_compute_brightness(connector, level);
index 30b7b3ea8836fc97318091ffa548f3e632bd2bf4..17bb64299bfd83bd553202110f7599fdcb3bad8d 100644 (file)
@@ -447,7 +447,7 @@ static int pwm_fan_resume(struct device *dev)
                return 0;
 
        pwm_get_args(ctx->pwm, &pargs);
-       duty = DIV_ROUND_UP(ctx->pwm_value * (pargs.period - 1), MAX_PWM);
+       duty = DIV_ROUND_UP_ULL(ctx->pwm_value * (pargs.period - 1), MAX_PWM);
        ret = pwm_config(ctx->pwm, duty, pargs.period);
        if (ret)
                return ret;
index 004b2ea9b5fde3968730260928eb60e80be21e58..276e939a5684634019be0303d9287d2848ab3802 100644 (file)
@@ -510,12 +510,12 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
            last->period > s2.period &&
            last->period <= state->period)
                dev_warn(chip->dev,
-                        ".apply didn't pick the best available period (requested: %u, applied: %u, possible: %u)\n",
+                        ".apply didn't pick the best available period (requested: %llu, applied: %llu, possible: %llu)\n",
                         state->period, s2.period, last->period);
 
        if (state->enabled && state->period < s2.period)
                dev_warn(chip->dev,
-                        ".apply is supposed to round down period (requested: %u, applied: %u)\n",
+                        ".apply is supposed to round down period (requested: %llu, applied: %llu)\n",
                         state->period, s2.period);
 
        if (state->enabled &&
@@ -524,14 +524,14 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
            last->duty_cycle > s2.duty_cycle &&
            last->duty_cycle <= state->duty_cycle)
                dev_warn(chip->dev,
-                        ".apply didn't pick the best available duty cycle (requested: %u/%u, applied: %u/%u, possible: %u/%u)\n",
+                        ".apply didn't pick the best available duty cycle (requested: %llu/%llu, applied: %llu/%llu, possible: %llu/%llu)\n",
                         state->duty_cycle, state->period,
                         s2.duty_cycle, s2.period,
                         last->duty_cycle, last->period);
 
        if (state->enabled && state->duty_cycle < s2.duty_cycle)
                dev_warn(chip->dev,
-                        ".apply is supposed to round down duty_cycle (requested: %u/%u, applied: %u/%u)\n",
+                        ".apply is supposed to round down duty_cycle (requested: %llu/%llu, applied: %llu/%llu)\n",
                         state->duty_cycle, state->period,
                         s2.duty_cycle, s2.period);
 
@@ -558,7 +558,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
            (s1.enabled && s1.period != last->period) ||
            (s1.enabled && s1.duty_cycle != last->duty_cycle)) {
                dev_err(chip->dev,
-                       ".apply is not idempotent (ena=%d pol=%d %u/%u) -> (ena=%d pol=%d %u/%u)\n",
+                       ".apply is not idempotent (ena=%d pol=%d %llu/%llu) -> (ena=%d pol=%d %llu/%llu)\n",
                        s1.enabled, s1.polarity, s1.duty_cycle, s1.period,
                        last->enabled, last->polarity, last->duty_cycle,
                        last->period);
@@ -1284,8 +1284,8 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
                if (state.enabled)
                        seq_puts(s, " enabled");
 
-               seq_printf(s, " period: %u ns", state.period);
-               seq_printf(s, " duty: %u ns", state.duty_cycle);
+               seq_printf(s, " period: %llu ns", state.period);
+               seq_printf(s, " duty: %llu ns", state.duty_cycle);
                seq_printf(s, " polarity: %s",
                           state.polarity ? "inverse" : "normal");
 
index 1f829edd8ee709c18b0b247c8ca945c607d4d505..79b1e58e946d76702f7682c20e97fc4890ca307a 100644 (file)
@@ -85,8 +85,6 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
        u64 tmp, multi, rate;
        u32 value, prescale;
 
-       rate = clk_get_rate(ip->clk);
-
        value = readl(ip->base + IPROC_PWM_CTRL_OFFSET);
 
        if (value & BIT(IPROC_PWM_CTRL_EN_SHIFT(pwm->hwpwm)))
@@ -99,6 +97,13 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
        else
                state->polarity = PWM_POLARITY_INVERSED;
 
+       rate = clk_get_rate(ip->clk);
+       if (rate == 0) {
+               state->period = 0;
+               state->duty_cycle = 0;
+               return;
+       }
+
        value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET);
        prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm);
        prescale &= IPROC_PWM_PRESCALE_MAX;
@@ -143,8 +148,7 @@ static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                value = rate * state->duty_cycle;
                duty = div64_u64(value, div);
 
-               if (period < IPROC_PWM_PERIOD_MIN ||
-                   duty < IPROC_PWM_DUTY_CYCLE_MIN)
+               if (period < IPROC_PWM_PERIOD_MIN)
                        return -EINVAL;
 
                if (period <= IPROC_PWM_PERIOD_MAX &&
index 81da91df2529ab0b8801620b4eb26490cfc5f0c6..16c5898b934a839e535e12573d7638b26aee8449 100644 (file)
@@ -138,7 +138,7 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
                dc = div64_u64(val, div);
 
                /* If duty_ns or period_ns are not achievable then return */
-               if (pc < PERIOD_COUNT_MIN || dc < DUTY_CYCLE_HIGH_MIN)
+               if (pc < PERIOD_COUNT_MIN)
                        return -EINVAL;
 
                /* If pc and dc are in bounds, the calculation is done */
index 924d39a797cf762f33586fa114c7310e78e01a3d..ba9500aca078a5240e6db012e5f48b4cb78a2ace 100644 (file)
@@ -43,7 +43,7 @@ static void clps711x_pwm_update_val(struct clps711x_chip *priv, u32 n, u32 v)
 static unsigned int clps711x_get_duty(struct pwm_device *pwm, unsigned int v)
 {
        /* Duty cycle 0..15 max */
-       return DIV_ROUND_CLOSEST(v * 0xf, pwm->args.period);
+       return DIV64_U64_ROUND_CLOSEST(v * 0xf, pwm->args.period);
 }
 
 static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
index 5f3d7f7e6aef0aa4a738a4bd28ff84e8814a6cf7..fcdf6befb83898de984402bd4c957217ccbad80d 100644 (file)
@@ -124,7 +124,7 @@ static int pwm_imx_tpm_round_state(struct pwm_chip *chip,
                real_state->duty_cycle = state->duty_cycle;
 
        tmp = (u64)p->mod * real_state->duty_cycle;
-       p->val = DIV_ROUND_CLOSEST_ULL(tmp, real_state->period);
+       p->val = DIV64_U64_ROUND_CLOSEST(tmp, real_state->period);
 
        real_state->polarity = state->polarity;
        real_state->enabled = state->enabled;
index 732a6f3701e8e329d3e362a5c3355baa24cfb7f7..c50d453552bd4f3a01d35c4445ba2272618cb286 100644 (file)
@@ -202,7 +202,7 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
        sr = readl(imx->mmio_base + MX3_PWMSR);
        fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr);
        if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) {
-               period_ms = DIV_ROUND_UP(pwm_get_period(pwm),
+               period_ms = DIV_ROUND_UP_ULL(pwm_get_period(pwm),
                                         NSEC_PER_MSEC);
                msleep(period_ms);
 
index 674f0e238ba01709e1ad40d48f44043d6a4bee8f..7d33e364643601e1ccce4d6f2ba399ce822cc740 100644 (file)
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
-#define IQS620_PWR_SETTINGS                    0xD2
+#define IQS620_PWR_SETTINGS                    0xd2
 #define IQS620_PWR_SETTINGS_PWM_OUT            BIT(7)
 
-#define IQS620_PWM_DUTY_CYCLE                  0xD8
+#define IQS620_PWM_DUTY_CYCLE                  0xd8
 
 #define IQS620_PWM_PERIOD_NS                   1000000
 
@@ -46,7 +46,8 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 {
        struct iqs620_pwm_private *iqs620_pwm;
        struct iqs62x_core *iqs62x;
-       int duty_scale, ret;
+       u64 duty_scale;
+       int ret;
 
        if (state->polarity != PWM_POLARITY_NORMAL)
                return -ENOTSUPP;
@@ -69,7 +70,7 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
         * For lower duty cycles (e.g. 0), the PWM output is simply disabled to
         * allow an external pull-down resistor to hold the GPIO3/LTX pin low.
         */
-       duty_scale = state->duty_cycle * 256 / IQS620_PWM_PERIOD_NS;
+       duty_scale = div_u64(state->duty_cycle * 256, IQS620_PWM_PERIOD_NS);
 
        mutex_lock(&iqs620_pwm->lock);
 
@@ -81,7 +82,7 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        }
 
        if (duty_scale) {
-               u8 duty_val = min(duty_scale - 1, 0xFF);
+               u8 duty_val = min_t(u64, duty_scale - 1, 0xff);
 
                ret = regmap_write(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE,
                                   duty_val);
@@ -93,7 +94,7 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 
        if (state->enabled && duty_scale) {
                ret = regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
-                                        IQS620_PWR_SETTINGS_PWM_OUT, 0xFF);
+                                        IQS620_PWR_SETTINGS_PWM_OUT, 0xff);
                if (ret)
                        goto err_mutex;
        }
@@ -159,7 +160,7 @@ static int iqs620_pwm_notifier(struct notifier_block *notifier,
 
        ret = regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
                                 IQS620_PWR_SETTINGS_PWM_OUT,
-                                iqs620_pwm->out_en ? 0xFF : 0);
+                                iqs620_pwm->out_en ? 0xff : 0);
 
 err_mutex:
        mutex_unlock(&iqs620_pwm->lock);
index b94e0d09c300f8bdc2cb23f85c39223d2968948f..ab001ce55178eabf019d5992c23ff75746afb6a2 100644 (file)
@@ -46,6 +46,7 @@ struct pwm_mediatek_of_data {
  * @clk_main: the clock used by PWM core
  * @clk_pwms: the clock used by each PWM channel
  * @clk_freq: the fix clock frequency of legacy MIPS SoC
+ * @soc: pointer to chip's platform data
  */
 struct pwm_mediatek_chip {
        struct pwm_chip chip;
index 0d31833db2e2cc335eced1030eae8348d8be2ab9..358db4ff9d4f352f1abb3c59b49db629a5638045 100644 (file)
@@ -14,7 +14,7 @@
  *   with a timer counter that goes up. When it overflows it gets
  *   reloaded with the load value and the pwm output goes up.
  *   When counter matches with match register, the output goes down.
- *   Reference Manual: http://www.ti.com/lit/ug/spruh73q/spruh73q.pdf
+ *   Reference Manual: https://www.ti.com/lit/ug/spruh73q/spruh73q.pdf
  *
  * Limitations:
  * - When PWM is stopped, timer counter gets stopped immediately. This
@@ -58,7 +58,7 @@
  * @mutex:             Mutex to protect pwm apply state
  * @dm_timer:          Pointer to omap dm timer.
  * @pdata:             Pointer to omap dm timer ops.
- * dm_timer_pdev:      Pointer to omap dm timer platform device
+ * @dm_timer_pdev:     Pointer to omap dm timer platform device
  */
 struct pwm_omap_dmtimer_chip {
        struct pwm_chip chip;
index cc63f9baa481942f03e8a8228ce0b312ae15be25..62de0bb859214f3dea5623a2fe83ba4c4fe211d9 100644 (file)
@@ -181,7 +181,7 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
         * consecutively
         */
        num = (u64)duty_cycle * (1U << PWM_SIFIVE_CMPWIDTH);
-       frac = DIV_ROUND_CLOSEST_ULL(num, state->period);
+       frac = DIV64_U64_ROUND_CLOSEST(num, state->period);
        /* The hardware cannot generate a 100% duty cycle */
        frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1);
 
index 67fca62524dc243fd16ba736b62c34bd0559d7ea..134c14621ee011c816830d26b1f7ac4974f40c40 100644 (file)
@@ -61,7 +61,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        do_div(div, NSEC_PER_SEC);
        if (!div) {
                /* Clock is too slow to achieve requested period. */
-               dev_dbg(priv->chip.dev, "Can't reach %u ns\n",  state->period);
+               dev_dbg(priv->chip.dev, "Can't reach %llu ns\n", state->period);
                return -EINVAL;
        }
 
index 18fbbe3277d0fe1c20598205d9a2e0b53d351da9..961c59c99bb3be30e287d3c9d4810a1e92cbe227 100644 (file)
@@ -285,7 +285,7 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        val = (duty & PWM_DTY_MASK) | PWM_PRD(period);
        sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
        sun4i_pwm->next_period[pwm->hwpwm] = jiffies +
-               usecs_to_jiffies(cstate.period / 1000 + 1);
+               nsecs_to_jiffies(cstate.period + 1000);
 
        if (state->polarity != PWM_POLARITY_NORMAL)
                ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
index ab38c8203b790f3ac6ecac0bb7d60d47c4c84775..683804c7d26cd18131bb6691ace7bd624eece0a5 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * ECAP PWM driver
  *
- * Copyright (C) 2012 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2012 Texas Instruments, Inc. - https://www.ti.com/
  */
 
 #include <linux/module.h>
index 7b4c770ce9d67854ece1d4e4ce4f6e011abc1222..0846917ff2d2aeef581c586a736ca3af108ca572 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * EHRPWM PWM driver
  *
- * Copyright (C) 2012 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2012 Texas Instruments, Inc. - https://www.ti.com/
  */
 
 #include <linux/module.h>
index 2389b86698468228a54ae50c2bae49b9663e5028..449dbc0f49edefeedd1b6667831e60382b1573d8 100644 (file)
@@ -42,7 +42,7 @@ static ssize_t period_show(struct device *child,
 
        pwm_get_state(pwm, &state);
 
-       return sprintf(buf, "%u\n", state.period);
+       return sprintf(buf, "%llu\n", state.period);
 }
 
 static ssize_t period_store(struct device *child,
@@ -52,10 +52,10 @@ static ssize_t period_store(struct device *child,
        struct pwm_export *export = child_to_pwm_export(child);
        struct pwm_device *pwm = export->pwm;
        struct pwm_state state;
-       unsigned int val;
+       u64 val;
        int ret;
 
-       ret = kstrtouint(buf, 0, &val);
+       ret = kstrtou64(buf, 0, &val);
        if (ret)
                return ret;
 
@@ -77,7 +77,7 @@ static ssize_t duty_cycle_show(struct device *child,
 
        pwm_get_state(pwm, &state);
 
-       return sprintf(buf, "%u\n", state.duty_cycle);
+       return sprintf(buf, "%llu\n", state.duty_cycle);
 }
 
 static ssize_t duty_cycle_store(struct device *child,
index eff64db2e02ee625cdcea418c92b9e4b59da860f..dfc760830eb90b221deab8257510561ba478618c 100644 (file)
@@ -601,7 +601,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
                pb->scale = data->max_brightness;
        }
 
-       pb->lth_brightness = data->lth_brightness * (state.period / pb->scale);
+       pb->lth_brightness = data->lth_brightness * (div_u64(state.period,
+                               pb->scale));
 
        props.type = BACKLIGHT_RAW;
        props.max_brightness = data->max_brightness;
index 8e06ba912d60adc8ef4dbbda480e2f348ae674c9..09425ec317ba2cbcc37da7b80f216b63036fc7b2 100644 (file)
@@ -312,7 +312,7 @@ static int ssd1307fb_init(struct ssd1307fb_par *par)
                /* Enable the PWM */
                pwm_enable(par->pwm);
 
-               dev_dbg(&par->client->dev, "Using PWM%d with a %dns period.\n",
+               dev_dbg(&par->client->dev, "Using PWM%d with a %lluns period.\n",
                        par->pwm->pwm, pwm_get_period(par->pwm));
        }
 
index 2635b2a55090d4353977c067d5556787d77e008f..a13ff383fa1d55c5d5f68a99beae3061bb2ff758 100644 (file)
@@ -39,7 +39,7 @@ enum pwm_polarity {
  * current PWM hardware state.
  */
 struct pwm_args {
-       unsigned int period;
+       u64 period;
        enum pwm_polarity polarity;
 };
 
@@ -56,8 +56,8 @@ enum {
  * @enabled: PWM enabled status
  */
 struct pwm_state {
-       unsigned int period;
-       unsigned int duty_cycle;
+       u64 period;
+       u64 duty_cycle;
        enum pwm_polarity polarity;
        bool enabled;
 };
@@ -107,13 +107,13 @@ static inline bool pwm_is_enabled(const struct pwm_device *pwm)
        return state.enabled;
 }
 
-static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
+static inline void pwm_set_period(struct pwm_device *pwm, u64 period)
 {
        if (pwm)
                pwm->state.period = period;
 }
 
-static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
+static inline u64 pwm_get_period(const struct pwm_device *pwm)
 {
        struct pwm_state state;
 
@@ -128,7 +128,7 @@ static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty)
                pwm->state.duty_cycle = duty;
 }
 
-static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
+static inline u64 pwm_get_duty_cycle(const struct pwm_device *pwm)
 {
        struct pwm_state state;