Loading drivers/pwm/core.c +15 −5 Original line number Diff line number Diff line Loading @@ -526,9 +526,19 @@ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state) if (state->period != pwm->state.period || state->duty_cycle != pwm->state.duty_cycle) { if (pwm->chip->ops->config_extend) { err = pwm->chip->ops->config_extend(pwm->chip, pwm, state->duty_cycle, state->period); } else { if (state->period > UINT_MAX) pr_warn("period %llu duty_cycle %llu will be truncated\n", state->period, state->duty_cycle); err = pwm->chip->ops->config(pwm->chip, pwm, state->duty_cycle, state->period); } if (err) return err; Loading Loading @@ -1017,8 +1027,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"); Loading drivers/pwm/sysfs.c +3 −3 Original line number Diff line number Diff line Loading @@ -50,7 +50,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, Loading Loading @@ -85,7 +85,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, Loading Loading @@ -220,7 +220,7 @@ static ssize_t capture_show(struct device *child, if (ret) return ret; return sprintf(buf, "%u %u\n", result.period, result.duty_cycle); return sprintf(buf, "%llu %llu\n", result.period, result.duty_cycle); } static ssize_t output_type_show(struct device *child, Loading include/linux/pwm.h +72 −7 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ enum pwm_polarity { * current PWM hardware state. */ struct pwm_args { unsigned int period; u64 period; enum pwm_polarity polarity; }; Loading @@ -65,9 +65,9 @@ enum pwm_output_type { * @cycles_per_duty: number of PWM period cycles an entry stays at */ struct pwm_output_pattern { unsigned int *duty_pattern; u64 *duty_pattern; unsigned int num_entries; unsigned int cycles_per_duty; u64 cycles_per_duty; }; /* Loading @@ -78,8 +78,8 @@ struct pwm_output_pattern { * @enabled: PWM enabled status */ struct pwm_state { unsigned int period; unsigned int duty_cycle; u64 period; u64 duty_cycle; enum pwm_polarity polarity; enum pwm_output_type output_type; struct pwm_output_pattern *output_pattern; Loading Loading @@ -135,12 +135,30 @@ static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period) pwm->state.period = period; } static inline void pwm_set_period_extend(struct pwm_device *pwm, u64 period) { if (pwm) pwm->state.period = period; } static inline unsigned int pwm_get_period(const struct pwm_device *pwm) { struct pwm_state state; pwm_get_state(pwm, &state); if (state.period > UINT_MAX) pr_warn("PWM period %llu is truncated\n", state.period); return (unsigned int)state.period; } static inline u64 pwm_get_period_extend(const struct pwm_device *pwm) { struct pwm_state state; pwm_get_state(pwm, &state); return state.period; } Loading @@ -150,12 +168,30 @@ static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty) pwm->state.duty_cycle = duty; } static inline void pwm_set_duty_cycle_extend(struct pwm_device *pwm, u64 duty) { if (pwm) pwm->state.duty_cycle = duty; } static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm) { struct pwm_state state; pwm_get_state(pwm, &state); if (state.duty_cycle > UINT_MAX) pr_warn("PWM duty cycle %llu is truncated\n", state.duty_cycle); return (unsigned int)state.duty_cycle; } static inline u64 pwm_get_duty_cycle_extend(const struct pwm_device *pwm) { struct pwm_state state; pwm_get_state(pwm, &state); return state.duty_cycle; } Loading Loading @@ -287,6 +323,8 @@ pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle, * @request: optional hook for requesting a PWM * @free: optional hook for freeing a PWM * @config: configure duty cycles and period length for this PWM * @config_extend: configure duty cycles and period length for this * PWM with u64 data type * @set_polarity: configure the polarity of this PWM * @capture: capture and report PWM signal * @enable: enable PWM output toggling Loading @@ -309,6 +347,8 @@ struct pwm_ops { void (*free)(struct pwm_chip *chip, struct pwm_device *pwm); int (*config)(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns); int (*config_extend)(struct pwm_chip *chip, struct pwm_device *pwm, u64 duty_ns, u64 period_ns); int (*set_polarity)(struct pwm_chip *chip, struct pwm_device *pwm, enum pwm_polarity polarity); int (*capture)(struct pwm_chip *chip, struct pwm_device *pwm, Loading Loading @@ -366,8 +406,8 @@ struct pwm_chip { * @duty_cycle: duty cycle of the PWM signal (in nanoseconds) */ struct pwm_capture { unsigned int period; unsigned int duty_cycle; u64 period; u64 duty_cycle; }; #if IS_ENABLED(CONFIG_PWM) Loading Loading @@ -420,6 +460,31 @@ static inline int pwm_config(struct pwm_device *pwm, int duty_ns, return pwm_apply_state(pwm, &state); } /** * pwm_config_extend() - change PWM period and duty length with u64 data type * @pwm: PWM device * @duty_ns: "on" time (in nanoseconds) * @period_ns: duration (in nanoseconds) of one cycle * * Returns: 0 on success or a negative error code on failure. */ static inline int pwm_config_extend(struct pwm_device *pwm, u64 duty_ns, u64 period_ns) { struct pwm_state state; if (!pwm) return -EINVAL; pwm_get_state(pwm, &state); if (state.duty_cycle == duty_ns && state.period == period_ns) return 0; state.duty_cycle = duty_ns; state.period = period_ns; return pwm_apply_state(pwm, &state); } /** * pwm_set_polarity() - configure the polarity of a PWM signal * @pwm: PWM device Loading Loading
drivers/pwm/core.c +15 −5 Original line number Diff line number Diff line Loading @@ -526,9 +526,19 @@ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state) if (state->period != pwm->state.period || state->duty_cycle != pwm->state.duty_cycle) { if (pwm->chip->ops->config_extend) { err = pwm->chip->ops->config_extend(pwm->chip, pwm, state->duty_cycle, state->period); } else { if (state->period > UINT_MAX) pr_warn("period %llu duty_cycle %llu will be truncated\n", state->period, state->duty_cycle); err = pwm->chip->ops->config(pwm->chip, pwm, state->duty_cycle, state->period); } if (err) return err; Loading Loading @@ -1017,8 +1027,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"); Loading
drivers/pwm/sysfs.c +3 −3 Original line number Diff line number Diff line Loading @@ -50,7 +50,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, Loading Loading @@ -85,7 +85,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, Loading Loading @@ -220,7 +220,7 @@ static ssize_t capture_show(struct device *child, if (ret) return ret; return sprintf(buf, "%u %u\n", result.period, result.duty_cycle); return sprintf(buf, "%llu %llu\n", result.period, result.duty_cycle); } static ssize_t output_type_show(struct device *child, Loading
include/linux/pwm.h +72 −7 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ enum pwm_polarity { * current PWM hardware state. */ struct pwm_args { unsigned int period; u64 period; enum pwm_polarity polarity; }; Loading @@ -65,9 +65,9 @@ enum pwm_output_type { * @cycles_per_duty: number of PWM period cycles an entry stays at */ struct pwm_output_pattern { unsigned int *duty_pattern; u64 *duty_pattern; unsigned int num_entries; unsigned int cycles_per_duty; u64 cycles_per_duty; }; /* Loading @@ -78,8 +78,8 @@ struct pwm_output_pattern { * @enabled: PWM enabled status */ struct pwm_state { unsigned int period; unsigned int duty_cycle; u64 period; u64 duty_cycle; enum pwm_polarity polarity; enum pwm_output_type output_type; struct pwm_output_pattern *output_pattern; Loading Loading @@ -135,12 +135,30 @@ static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period) pwm->state.period = period; } static inline void pwm_set_period_extend(struct pwm_device *pwm, u64 period) { if (pwm) pwm->state.period = period; } static inline unsigned int pwm_get_period(const struct pwm_device *pwm) { struct pwm_state state; pwm_get_state(pwm, &state); if (state.period > UINT_MAX) pr_warn("PWM period %llu is truncated\n", state.period); return (unsigned int)state.period; } static inline u64 pwm_get_period_extend(const struct pwm_device *pwm) { struct pwm_state state; pwm_get_state(pwm, &state); return state.period; } Loading @@ -150,12 +168,30 @@ static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty) pwm->state.duty_cycle = duty; } static inline void pwm_set_duty_cycle_extend(struct pwm_device *pwm, u64 duty) { if (pwm) pwm->state.duty_cycle = duty; } static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm) { struct pwm_state state; pwm_get_state(pwm, &state); if (state.duty_cycle > UINT_MAX) pr_warn("PWM duty cycle %llu is truncated\n", state.duty_cycle); return (unsigned int)state.duty_cycle; } static inline u64 pwm_get_duty_cycle_extend(const struct pwm_device *pwm) { struct pwm_state state; pwm_get_state(pwm, &state); return state.duty_cycle; } Loading Loading @@ -287,6 +323,8 @@ pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle, * @request: optional hook for requesting a PWM * @free: optional hook for freeing a PWM * @config: configure duty cycles and period length for this PWM * @config_extend: configure duty cycles and period length for this * PWM with u64 data type * @set_polarity: configure the polarity of this PWM * @capture: capture and report PWM signal * @enable: enable PWM output toggling Loading @@ -309,6 +347,8 @@ struct pwm_ops { void (*free)(struct pwm_chip *chip, struct pwm_device *pwm); int (*config)(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns); int (*config_extend)(struct pwm_chip *chip, struct pwm_device *pwm, u64 duty_ns, u64 period_ns); int (*set_polarity)(struct pwm_chip *chip, struct pwm_device *pwm, enum pwm_polarity polarity); int (*capture)(struct pwm_chip *chip, struct pwm_device *pwm, Loading Loading @@ -366,8 +406,8 @@ struct pwm_chip { * @duty_cycle: duty cycle of the PWM signal (in nanoseconds) */ struct pwm_capture { unsigned int period; unsigned int duty_cycle; u64 period; u64 duty_cycle; }; #if IS_ENABLED(CONFIG_PWM) Loading Loading @@ -420,6 +460,31 @@ static inline int pwm_config(struct pwm_device *pwm, int duty_ns, return pwm_apply_state(pwm, &state); } /** * pwm_config_extend() - change PWM period and duty length with u64 data type * @pwm: PWM device * @duty_ns: "on" time (in nanoseconds) * @period_ns: duration (in nanoseconds) of one cycle * * Returns: 0 on success or a negative error code on failure. */ static inline int pwm_config_extend(struct pwm_device *pwm, u64 duty_ns, u64 period_ns) { struct pwm_state state; if (!pwm) return -EINVAL; pwm_get_state(pwm, &state); if (state.duty_cycle == duty_ns && state.period == period_ns) return 0; state.duty_cycle = duty_ns; state.period = period_ns; return pwm_apply_state(pwm, &state); } /** * pwm_set_polarity() - configure the polarity of a PWM signal * @pwm: PWM device Loading