// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Generic pwmlib implementation
 *
 * Copyright (C) 2011 Sascha Hauer <s.hauer@pengutronix.de>
 * Copyright (C) 2011-2012 Avionic Design GmbH
 */

#define DEFAULT_SYMBOL_NAMESPACE "PWM"

#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/idr.h>
#include <linux/of.h>
#include <linux/pwm.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>

#include <dt-bindings/pwm/pwm.h>

#include <uapi/linux/pwm.h>

#define CREATE_TRACE_POINTS
#include <trace/events/pwm.h>

#define PWM_MINOR_COUNT 256

/* protects access to pwm_chips */
static DEFINE_MUTEX(pwm_lock);

static DEFINE_IDR(pwm_chips);

static void pwmchip_lock(struct pwm_chip *chip)
{
	if (chip->atomic)
		spin_lock(&chip->atomic_lock);
	else
		mutex_lock(&chip->nonatomic_lock);
}

static void pwmchip_unlock(struct pwm_chip *chip)
{
	if (chip->atomic)
		spin_unlock(&chip->atomic_lock);
	else
		mutex_unlock(&chip->nonatomic_lock);
}

DEFINE_GUARD(pwmchip, struct pwm_chip *, pwmchip_lock(_T), pwmchip_unlock(_T))

static bool pwm_wf_valid(const struct pwm_waveform *wf)
{
	/*
	 * For now restrict waveforms to period_length_ns <= S64_MAX to provide
	 * some space for future extensions. One possibility is to simplify
	 * representing waveforms with inverted polarity using negative values
	 * somehow.
	 */
	if (wf->period_length_ns > S64_MAX)
		return false;

	if (wf->duty_length_ns > wf->period_length_ns)
		return false;

	/*
	 * .duty_offset_ns is supposed to be smaller than .period_length_ns, apart
	 * from the corner case .duty_offset_ns == 0 && .period_length_ns == 0.
	 */
	if (wf->duty_offset_ns && wf->duty_offset_ns >= wf->period_length_ns)
		return false;

	return true;
}

static void pwm_wf2state(const struct pwm_waveform *wf, struct pwm_state *state)
{
	if (wf->period_length_ns) {
		if (wf->duty_length_ns + wf->duty_offset_ns < wf->period_length_ns)
			*state = (struct pwm_state){
				.enabled = true,
				.polarity = PWM_POLARITY_NORMAL,
				.period = wf->period_length_ns,
				.duty_cycle = wf->duty_length_ns,
			};
		else
			*state = (struct pwm_state){
				.enabled = true,
				.polarity = PWM_POLARITY_INVERSED,
				.period = wf->period_length_ns,
				.duty_cycle = wf->period_length_ns - wf->duty_length_ns,
			};
	} else {
		*state = (struct pwm_state){
			.enabled = false,
		};
	}
}

static void pwm_state2wf(const struct pwm_state *state, struct pwm_waveform *wf)
{
	if (state->enabled) {
		if (state->polarity == PWM_POLARITY_NORMAL)
			*wf = (struct pwm_waveform){
				.period_length_ns = state->period,
				.duty_length_ns = state->duty_cycle,
				.duty_offset_ns = 0,
			};
		else
			*wf = (struct pwm_waveform){
				.period_length_ns = state->period,
				.duty_length_ns = state->period - state->duty_cycle,
				.duty_offset_ns = state->duty_cycle,
			};
	} else {
		*wf = (struct pwm_waveform){
			.period_length_ns = 0,
		};
	}
}

static int pwmwfcmp(const struct pwm_waveform *a, const struct pwm_waveform *b)
{
	if (a->period_length_ns > b->period_length_ns)
		return 1;

	if (a->period_length_ns < b->period_length_ns)
		return -1;

	if (a->duty_length_ns > b->duty_length_ns)
		return 1;

	if (a->duty_length_ns < b->duty_length_ns)
		return -1;

	if (a->duty_offset_ns > b->duty_offset_ns)
		return 1;

	if (a->duty_offset_ns < b->duty_offset_ns)
		return -1;

	return 0;
}

static bool pwm_check_rounding(const struct pwm_waveform *wf,
			       const struct pwm_waveform *wf_rounded)
{
	if (!wf->period_length_ns)
		return true;

	if (wf->period_length_ns < wf_rounded->period_length_ns)
		return false;

	if (wf->duty_length_ns < wf_rounded->duty_length_ns)
		return false;

	if (wf->duty_offset_ns < wf_rounded->duty_offset_ns)
		return false;

	return true;
}

static int __pwm_round_waveform_tohw(struct pwm_chip *chip, struct pwm_device *pwm,
				     const struct pwm_waveform *wf, void *wfhw)
{
	const struct pwm_ops *ops = chip->ops;
	int ret;

	ret = ops->round_waveform_tohw(chip, pwm, wf, wfhw);
	trace_pwm_round_waveform_tohw(pwm, wf, wfhw, ret);

	return ret;
}

static int __pwm_round_waveform_fromhw(struct pwm_chip *chip, struct pwm_device *pwm,
				       const void *wfhw, struct pwm_waveform *wf)
{
	const struct pwm_ops *ops = chip->ops;
	int ret;

	ret = ops->round_waveform_fromhw(chip, pwm, wfhw, wf);
	trace_pwm_round_waveform_fromhw(pwm, wfhw, wf, ret);

	return ret;
}

static int __pwm_read_waveform(struct pwm_chip *chip, struct pwm_device *pwm, void *wfhw)
{
	const struct pwm_ops *ops = chip->ops;
	int ret;

	ret = ops->read_waveform(chip, pwm, wfhw);
	trace_pwm_read_waveform(pwm, wfhw, ret);

	return ret;
}

static int __pwm_write_waveform(struct pwm_chip *chip, struct pwm_device *pwm, const void *wfhw)
{
	const struct pwm_ops *ops = chip->ops;
	int ret;

	ret = ops->write_waveform(chip, pwm, wfhw);
	trace_pwm_write_waveform(pwm, wfhw, ret);

	return ret;
}

/**
 * pwm_round_waveform_might_sleep - Query hardware capabilities
 * Cannot be used in atomic context.
 * @pwm: PWM device
 * @wf: waveform to round and output parameter
 *
 * Typically a given waveform cannot be implemented exactly by hardware, e.g.
 * because hardware only supports coarse period resolution or no duty_offset.
 * This function returns the actually implemented waveform if you pass @wf to
 * pwm_set_waveform_might_sleep() now.
 *
 * Note however that the world doesn't stop turning when you call it, so when
 * doing::
 *
 *   pwm_round_waveform_might_sleep(mypwm, &wf);
 *   pwm_set_waveform_might_sleep(mypwm, &wf, true);
 *
 * the latter might fail, e.g. because an input clock changed its rate between
 * these two calls and the waveform determined by
 * pwm_round_waveform_might_sleep() cannot be implemented any more.
 *
 * Usually all values passed in @wf are rounded down to the nearest possible
 * value (in the order period_length_ns, duty_length_ns and then
 * duty_offset_ns). Only if this isn't possible, a value might grow. See the
 * documentation for pwm_set_waveform_might_sleep() for a more formal
 * description.
 *
 * Returns: 0 on success, 1 if at least one value had to be rounded up or a
 * negative errno.
 * Context: May sleep.
 */
int pwm_round_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *wf)
{
	struct pwm_chip *chip = pwm->chip;
	const struct pwm_ops *ops = chip->ops;
	struct pwm_waveform wf_req = *wf;
	char wfhw[PWM_WFHWSIZE];
	int ret_tohw, ret_fromhw;

	BUG_ON(PWM_WFHWSIZE < ops->sizeof_wfhw);

	if (!pwmchip_supports_waveform(chip))
		return -EOPNOTSUPP;

	if (!pwm_wf_valid(wf))
		return -EINVAL;

	guard(pwmchip)(chip);

	if (!chip->operational)
		return -ENODEV;

	ret_tohw = __pwm_round_waveform_tohw(chip, pwm, wf, wfhw);
	if (ret_tohw < 0)
		return ret_tohw;

	if (IS_ENABLED(CONFIG_PWM_DEBUG) && ret_tohw > 1)
		dev_err(&chip->dev, "Unexpected return value from __pwm_round_waveform_tohw: requested %llu/%llu [+%llu], return value %d\n",
			wf_req.duty_length_ns, wf_req.period_length_ns, wf_req.duty_offset_ns, ret_tohw);

	ret_fromhw = __pwm_round_waveform_fromhw(chip, pwm, wfhw, wf);
	if (ret_fromhw < 0)
		return ret_fromhw;

	if (IS_ENABLED(CONFIG_PWM_DEBUG) && ret_fromhw > 0)
		dev_err(&chip->dev, "Unexpected return value from __pwm_round_waveform_fromhw: requested %llu/%llu [+%llu], return value %d\n",
			wf_req.duty_length_ns, wf_req.period_length_ns, wf_req.duty_offset_ns, ret_fromhw);

	if (IS_ENABLED(CONFIG_PWM_DEBUG) &&
	    (ret_tohw == 0) != pwm_check_rounding(&wf_req, wf))
		dev_err(&chip->dev, "Wrong rounding: requested %llu/%llu [+%llu], result %llu/%llu [+%llu], ret: %d\n",
			wf_req.duty_length_ns, wf_req.period_length_ns, wf_req.duty_offset_ns,
			wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns, ret_tohw);

	return ret_tohw;
}
EXPORT_SYMBOL_GPL(pwm_round_waveform_might_sleep);

/**
 * pwm_get_waveform_might_sleep - Query hardware about current configuration
 * Cannot be used in atomic context.
 * @pwm: PWM device
 * @wf: output parameter
 *
 * Stores the current configuration of the PWM in @wf. Note this is the
 * equivalent of pwm_get_state_hw() (and not pwm_get_state()) for pwm_waveform.
 *
 * Returns: 0 on success or a negative errno
 * Context: May sleep.
 */
int pwm_get_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *wf)
{
	struct pwm_chip *chip = pwm->chip;
	const struct pwm_ops *ops = chip->ops;
	char wfhw[PWM_WFHWSIZE];
	int err;

	BUG_ON(PWM_WFHWSIZE < ops->sizeof_wfhw);

	if (!pwmchip_supports_waveform(chip) || !ops->read_waveform)
		return -EOPNOTSUPP;

	guard(pwmchip)(chip);

	if (!chip->operational)
		return -ENODEV;

	err = __pwm_read_waveform(chip, pwm, &wfhw);
	if (err)
		return err;

	return __pwm_round_waveform_fromhw(chip, pwm, &wfhw, wf);
}
EXPORT_SYMBOL_GPL(pwm_get_waveform_might_sleep);

/* Called with the pwmchip lock held */
static int __pwm_set_waveform(struct pwm_device *pwm,
			      const struct pwm_waveform *wf,
			      bool exact)
{
	struct pwm_chip *chip = pwm->chip;
	const struct pwm_ops *ops = chip->ops;
	char wfhw[PWM_WFHWSIZE];
	struct pwm_waveform wf_rounded;
	int err, ret_tohw;

	BUG_ON(PWM_WFHWSIZE < ops->sizeof_wfhw);

	if (!pwmchip_supports_waveform(chip))
		return -EOPNOTSUPP;

	if (!pwm_wf_valid(wf))
		return -EINVAL;

	ret_tohw = __pwm_round_waveform_tohw(chip, pwm, wf, &wfhw);
	if (ret_tohw < 0)
		return ret_tohw;

	if ((IS_ENABLED(CONFIG_PWM_DEBUG) || exact) && wf->period_length_ns) {
		err = __pwm_round_waveform_fromhw(chip, pwm, &wfhw, &wf_rounded);
		if (err)
			return err;

		if (IS_ENABLED(CONFIG_PWM_DEBUG) && (ret_tohw == 0) != pwm_check_rounding(wf, &wf_rounded))
			dev_err(&chip->dev, "Wrong rounding: requested %llu/%llu [+%llu], result %llu/%llu [+%llu], ret: %d\n",
				wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns,
				wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns, ret_tohw);

		if (exact && pwmwfcmp(wf, &wf_rounded)) {
			dev_dbg(&chip->dev, "Requested no rounding, but %llu/%llu [+%llu] -> %llu/%llu [+%llu]\n",
				wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns,
				wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns);

			return 1;
		}
	}

	err = __pwm_write_waveform(chip, pwm, &wfhw);
	if (err)
		return err;

	/* update .state */
	pwm_wf2state(wf, &pwm->state);

	if (IS_ENABLED(CONFIG_PWM_DEBUG) && ops->read_waveform && wf->period_length_ns) {
		struct pwm_waveform wf_set;

		err = __pwm_read_waveform(chip, pwm, &wfhw);
		if (err)
			/* maybe ignore? */
			return err;

		err = __pwm_round_waveform_fromhw(chip, pwm, &wfhw, &wf_set);
		if (err)
			/* maybe ignore? */
			return err;

		if (pwmwfcmp(&wf_set, &wf_rounded) != 0)
			dev_err(&chip->dev,
				"Unexpected setting: requested %llu/%llu [+%llu], expected %llu/%llu [+%llu], set %llu/%llu [+%llu]\n",
				wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns,
				wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns,
				wf_set.duty_length_ns, wf_set.period_length_ns, wf_set.duty_offset_ns);
	}

	return ret_tohw;
}

/**
 * pwm_set_waveform_might_sleep - Apply a new waveform
 * Cannot be used in atomic context.
 * @pwm: PWM device
 * @wf: The waveform to apply
 * @exact: If true no rounding is allowed
 *
 * Typically a requested waveform cannot be implemented exactly, e.g. because
 * you requested .period_length_ns = 100 ns, but the hardware can only set
 * periods that are a multiple of 8.5 ns. With that hardware passing @exact =
 * true results in pwm_set_waveform_might_sleep() failing and returning -EDOM.
 * If @exact = false you get a period of 93.5 ns (i.e. the biggest period not
 * bigger than the requested value).
 * Note that even with @exact = true, some rounding by less than 1 ns is
 * possible/needed. In the above example requesting .period_length_ns = 94 and
 * @exact = true, you get the hardware configured with period = 93.5 ns.
 *
 * Let C be the set of possible hardware configurations for a given PWM device,
 * consisting of tuples (p, d, o) where p is the period length, d is the duty
 * length and o the duty offset.
 *
 * The following algorithm is implemented to pick the hardware setting
 * (p, d, o) ∈ C for a given request (p', d', o') with @exact = false::
 *
 *   p = max( { ṗ | ∃ ḋ, ȯ : (ṗ, ḋ, ȯ) ∈ C ∧ ṗ ≤ p' } ∪ { min({ ṗ | ∃ ḋ, ȯ : (ṗ, ḋ, ȯ) ∈ C }) })
 *   d = max( { ḋ | ∃ ȯ : (p, ḋ, ȯ) ∈ C ∧ ḋ ≤ d' } ∪ { min({ ḋ | ∃ ȯ : (p, ḋ, ȯ) ∈ C }) })
 *   o = max( { ȯ | (p, d, ȯ) ∈ C ∧ ȯ ≤ o' } ∪ { min({ ȯ | (p, d, ȯ) ∈ C }) })
 *
 * In words: The chosen period length is the maximal possible period length not
 * bigger than the requested period length and if that doesn't exist, the
 * minimal period length. The chosen duty length is the maximal possible duty
 * length that is compatible with the chosen period length and isn't bigger than
 * the requested duty length. Again if such a value doesn't exist, the minimal
 * duty length compatible with the chosen period is picked. After that the duty
 * offset compatible with the chosen period and duty length is chosen in the
 * same way.
 *
 * Returns: 0 on success, -EDOM if setting failed due to the exact waveform not
 * being possible (if @exact), or a different negative errno on failure.
 * Context: May sleep.
 */
int pwm_set_waveform_might_sleep(struct pwm_device *pwm,
				 const struct pwm_waveform *wf, bool exact)
{
	struct pwm_chip *chip = pwm->chip;
	int err;

	might_sleep();

	guard(pwmchip)(chip);

	if (!chip->operational)
		return -ENODEV;

	if (IS_ENABLED(CONFIG_PWM_DEBUG) && chip->atomic) {
		/*
		 * Catch any drivers that have been marked as atomic but
		 * that will sleep anyway.
		 */
		non_block_start();
		err = __pwm_set_waveform(pwm, wf, exact);
		non_block_end();
	} else {
		err = __pwm_set_waveform(pwm, wf, exact);
	}

	/*
	 * map err == 1 to -EDOM for exact requests and 0 for !exact ones. Also
	 * make sure that -EDOM is only returned in exactly that case. Note that
	 * __pwm_set_waveform() should never return -EDOM which justifies the
	 * unlikely().
	 */
	if (unlikely(err == -EDOM))
		err = -EINVAL;
	else if (exact && err == 1)
		err = -EDOM;
	else if (err == 1)
		err = 0;

	return err;
}
EXPORT_SYMBOL_GPL(pwm_set_waveform_might_sleep);

static void pwm_apply_debug(struct pwm_device *pwm,
			    const struct pwm_state *state)
{
	struct pwm_state *last = &pwm->last;
	struct pwm_chip *chip = pwm->chip;
	struct pwm_state s1 = { 0 }, s2 = { 0 };
	int err;

	if (!IS_ENABLED(CONFIG_PWM_DEBUG))
		return;

	/* No reasonable diagnosis possible without .get_state() */
	if (!chip->ops->get_state)
		return;

	/*
	 * If a disabled PWM was requested the result is unspecified, so nothing
	 * to check.
	 */
	if (!state->enabled)
		return;

	/*
	 * *state was just applied. Read out the hardware state and do some
	 * checks.
	 */

	err = chip->ops->get_state(chip, pwm, &s1);
	trace_pwm_get(pwm, &s1, err);
	if (err)
		/* If that failed there isn't much to debug */
		return;

	/*
	 * If the PWM was disabled that's maybe strange but there is nothing
	 * that can be sensibly checked then. So return early.
	 */
	if (!s1.enabled)
		return;

	/*
	 * The lowlevel driver either ignored .polarity (which is a bug) or as
	 * best effort inverted .polarity and fixed .duty_cycle respectively.
	 * Undo this inversion and fixup for further tests.
	 */
	if (s1.polarity != state->polarity) {
		s2.polarity = state->polarity;
		s2.duty_cycle = s1.period - s1.duty_cycle;
		s2.period = s1.period;
		s2.enabled = true;
	} else {
		s2 = s1;
	}

	if (s2.polarity != state->polarity &&
	    s2.duty_cycle < s2.period)
		dev_warn(pwmchip_parent(chip), ".apply ignored .polarity\n");

	if (last->polarity == state->polarity &&
	    last->period > s2.period &&
	    last->period <= state->period)
		dev_warn(pwmchip_parent(chip),
			 ".apply didn't pick the best available period (requested: %llu, applied: %llu, possible: %llu)\n",
			 state->period, s2.period, last->period);

	/*
	 * Rounding period up is fine only if duty_cycle is 0 then, because a
	 * flat line doesn't have a characteristic period.
	 */
	if (state->period < s2.period && s2.duty_cycle)
		dev_warn(pwmchip_parent(chip),
			 ".apply is supposed to round down period (requested: %llu, applied: %llu)\n",
			 state->period, s2.period);

	if (last->polarity == state->polarity &&
	    last->period == s2.period &&
	    last->duty_cycle > s2.duty_cycle &&
	    last->duty_cycle <= state->duty_cycle)
		dev_warn(pwmchip_parent(chip),
			 ".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->duty_cycle < s2.duty_cycle)
		dev_warn(pwmchip_parent(chip),
			 ".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);

	/* reapply the state that the driver reported being configured. */
	err = chip->ops->apply(chip, pwm, &s1);
	trace_pwm_apply(pwm, &s1, err);
	if (err) {
		*last = s1;
		dev_err(pwmchip_parent(chip), "failed to reapply current setting\n");
		return;
	}

	*last = (struct pwm_state){ 0 };
	err = chip->ops->get_state(chip, pwm, last);
	trace_pwm_get(pwm, last, err);
	if (err)
		return;

	/* reapplication of the current state should give an exact match */
	if (s1.enabled != last->enabled ||
	    s1.polarity != last->polarity ||
	    (s1.enabled && s1.period != last->period) ||
	    (s1.enabled && s1.duty_cycle != last->duty_cycle)) {
		dev_err(pwmchip_parent(chip),
			".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);
	}
}

static bool pwm_state_valid(const struct pwm_state *state)
{
	/*
	 * For a disabled state all other state description is irrelevant and
	 * and supposed to be ignored. So also ignore any strange values and
	 * consider the state ok.
	 */
	if (!state->enabled)
		return true;

	if (!state->period)
		return false;

	if (state->duty_cycle > state->period)
		return false;

	return true;
}

static int __pwm_apply(struct pwm_device *pwm, const struct pwm_state *state)
{
	struct pwm_chip *chip;
	const struct pwm_ops *ops;
	int err;

	if (!pwm || !state)
		return -EINVAL;

	if (!pwm_state_valid(state)) {
		/*
		 * Allow to transition from one invalid state to another.
		 * This ensures that you can e.g. change the polarity while
		 * the period is zero. (This happens on stm32 when the hardware
		 * is in its poweron default state.) This greatly simplifies
		 * working with the sysfs API where you can only change one
		 * parameter at a time.
		 */
		if (!pwm_state_valid(&pwm->state)) {
			pwm->state = *state;
			return 0;
		}

		return -EINVAL;
	}

	chip = pwm->chip;
	ops = chip->ops;

	if (state->period == pwm->state.period &&
	    state->duty_cycle == pwm->state.duty_cycle &&
	    state->polarity == pwm->state.polarity &&
	    state->enabled == pwm->state.enabled &&
	    state->usage_power == pwm->state.usage_power)
		return 0;

	if (pwmchip_supports_waveform(chip)) {
		struct pwm_waveform wf;
		char wfhw[PWM_WFHWSIZE];

		BUG_ON(PWM_WFHWSIZE < ops->sizeof_wfhw);

		pwm_state2wf(state, &wf);

		/*
		 * The rounding is wrong here for states with inverted polarity.
		 * While .apply() rounds down duty_cycle (which represents the
		 * time from the start of the period to the inner edge),
		 * .round_waveform_tohw() rounds down the time the PWM is high.
		 * Can be fixed if the need arises, until reported otherwise
		 * let's assume that consumers don't care.
		 */

		err = __pwm_round_waveform_tohw(chip, pwm, &wf, &wfhw);
		if (err) {
			if (err > 0)
				/*
				 * This signals an invalid request, typically
				 * the requested period (or duty_offset) is
				 * smaller than possible with the hardware.
				 */
				return -EINVAL;

			return err;
		}

		if (IS_ENABLED(CONFIG_PWM_DEBUG)) {
			struct pwm_waveform wf_rounded;

			err = __pwm_round_waveform_fromhw(chip, pwm, &wfhw, &wf_rounded);
			if (err)
				return err;

			if (!pwm_check_rounding(&wf, &wf_rounded))
				dev_err(&chip->dev, "Wrong rounding: requested %llu/%llu [+%llu], result %llu/%llu [+%llu]\n",
					wf.duty_length_ns, wf.period_length_ns, wf.duty_offset_ns,
					wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns);
		}

		err = __pwm_write_waveform(chip, pwm, &wfhw);
		if (err)
			return err;

		pwm->state = *state;

	} else {
		err = ops->apply(chip, pwm, state);
		trace_pwm_apply(pwm, state, err);
		if (err)
			return err;

		pwm->state = *state;

		/*
		 * only do this after pwm->state was applied as some
		 * implementations of .get_state() depend on this
		 */
		pwm_apply_debug(pwm, state);
	}

	return 0;
}

/**
 * pwm_apply_might_sleep() - atomically apply a new state to a PWM device
 * Cannot be used in atomic context.
 * @pwm: PWM device
 * @state: new state to apply
 *
 * Returns: 0 on success, or a negative errno
 * Context: May sleep.
 */
int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state)
{
	int err;
	struct pwm_chip *chip = pwm->chip;

	/*
	 * 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_might_sleep() from atomic context
	 * is a bad idea. So make it explicit that calling this function might
	 * sleep.
	 */
	might_sleep();

	guard(pwmchip)(chip);

	if (!chip->operational)
		return -ENODEV;

	if (IS_ENABLED(CONFIG_PWM_DEBUG) && chip->atomic) {
		/*
		 * Catch any drivers that have been marked as atomic but
		 * that will sleep anyway.
		 */
		non_block_start();
		err = __pwm_apply(pwm, state);
		non_block_end();
	} else {
		err = __pwm_apply(pwm, state);
	}

	return err;
}
EXPORT_SYMBOL_GPL(pwm_apply_might_sleep);

/**
 * pwm_apply_atomic() - apply a new state to a PWM device from atomic context
 * Not all PWM devices support this function, check with pwm_might_sleep().
 * @pwm: PWM device
 * @state: new state to apply
 *
 * Returns: 0 on success, or a negative errno
 * Context: Any
 */
int pwm_apply_atomic(struct pwm_device *pwm, const struct pwm_state *state)
{
	struct pwm_chip *chip = pwm->chip;

	WARN_ONCE(!chip->atomic,
		  "sleeping PWM driver used in atomic context\n");

	guard(pwmchip)(chip);

	if (!chip->operational)
		return -ENODEV;

	return __pwm_apply(pwm, state);
}
EXPORT_SYMBOL_GPL(pwm_apply_atomic);

/**
 * pwm_get_state_hw() - get the current PWM state from hardware
 * @pwm: PWM device
 * @state: state to fill with the current PWM state
 *
 * Similar to pwm_get_state() but reads the current PWM state from hardware
 * instead of the requested state.
 *
 * Returns: 0 on success or a negative error code on failure.
 * Context: May sleep.
 */
int pwm_get_state_hw(struct pwm_device *pwm, struct pwm_state *state)
{
	struct pwm_chip *chip = pwm->chip;
	const struct pwm_ops *ops = chip->ops;
	int ret = -EOPNOTSUPP;

	might_sleep();

	guard(pwmchip)(chip);

	if (!chip->operational)
		return -ENODEV;

	if (pwmchip_supports_waveform(chip) && ops->read_waveform) {
		char wfhw[PWM_WFHWSIZE];
		struct pwm_waveform wf;

		BUG_ON(PWM_WFHWSIZE < ops->sizeof_wfhw);

		ret = __pwm_read_waveform(chip, pwm, &wfhw);
		if (ret)
			return ret;

		ret = __pwm_round_waveform_fromhw(chip, pwm, &wfhw, &wf);
		if (ret)
			return ret;

		pwm_wf2state(&wf, state);

	} else if (ops->get_state) {
		ret = ops->get_state(chip, pwm, state);
		trace_pwm_get(pwm, state, ret);
	}

	return ret;
}
EXPORT_SYMBOL_GPL(pwm_get_state_hw);

/**
 * pwm_adjust_config() - adjust the current PWM config to the PWM arguments
 * @pwm: PWM device
 *
 * This function will adjust the PWM config to the PWM arguments provided
 * by the DT or PWM lookup table. This is particularly useful to adapt
 * the bootloader config to the Linux one.
 *
 * Returns: 0 on success or a negative error code on failure.
 * Context: May sleep.
 */
int pwm_adjust_config(struct pwm_device *pwm)
{
	struct pwm_state state;
	struct pwm_args pargs;

	pwm_get_args(pwm, &pargs);
	pwm_get_state(pwm, &state);

	/*
	 * If the current period is zero it means that either the PWM driver
	 * does not support initial state retrieval or the PWM has not yet
	 * been configured.
	 *
	 * In either case, we setup the new period and polarity, and assign a
	 * duty cycle of 0.
	 */
	if (!state.period) {
		state.duty_cycle = 0;
		state.period = pargs.period;
		state.polarity = pargs.polarity;

		return pwm_apply_might_sleep(pwm, &state);
	}

	/*
	 * Adjust the PWM duty cycle/period based on the period value provided
	 * in PWM args.
	 */
	if (pargs.period != state.period) {
		u64 dutycycle = (u64)state.duty_cycle * pargs.period;

		do_div(dutycycle, state.period);
		state.duty_cycle = dutycycle;
		state.period = pargs.period;
	}

	/*
	 * If the polarity changed, we should also change the duty cycle.
	 */
	if (pargs.polarity != state.polarity) {
		state.polarity = pargs.polarity;
		state.duty_cycle = state.period - state.duty_cycle;
	}

	return pwm_apply_might_sleep(pwm, &state);
}
EXPORT_SYMBOL_GPL(pwm_adjust_config);

/**
 * pwm_capture() - capture and report a PWM signal
 * @pwm: PWM device
 * @result: structure to fill with capture result
 * @timeout: time to wait, in milliseconds, before giving up on capture
 *
 * Returns: 0 on success or a negative error code on failure.
 */
static int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result,
		       unsigned long timeout)
{
	struct pwm_chip *chip = pwm->chip;
	const struct pwm_ops *ops = chip->ops;

	if (!ops->capture)
		return -ENOSYS;

	/*
	 * Holding the pwm_lock is probably not needed. If you use pwm_capture()
	 * and you're interested to speed it up, please convince yourself it's
	 * really not needed, test and then suggest a patch on the mailing list.
	 */
	guard(mutex)(&pwm_lock);

	guard(pwmchip)(chip);

	if (!chip->operational)
		return -ENODEV;

	return ops->capture(chip, pwm, result, timeout);
}

static struct pwm_chip *pwmchip_find_by_name(const char *name)
{
	struct pwm_chip *chip;
	unsigned long id, tmp;

	if (!name)
		return NULL;

	guard(mutex)(&pwm_lock);

	idr_for_each_entry_ul(&pwm_chips, chip, tmp, id) {
		if (device_match_name(pwmchip_parent(chip), name))
			return chip;
	}

	return NULL;
}

static int pwm_device_request(struct pwm_device *pwm, const char *label)
{
	int err;
	struct pwm_chip *chip = pwm->chip;
	const struct pwm_ops *ops = chip->ops;

	if (test_bit(PWMF_REQUESTED, &pwm->flags))
		return -EBUSY;

	/*
	 * This function is called while holding pwm_lock. As .operational only
	 * changes while holding this lock, checking it here without holding the
	 * chip lock is fine.
	 */
	if (!chip->operational)
		return -ENODEV;

	if (!try_module_get(chip->owner))
		return -ENODEV;

	if (!get_device(&chip->dev)) {
		err = -ENODEV;
		goto err_get_device;
	}

	if (ops->request) {
		err = ops->request(chip, pwm);
		if (err) {
			put_device(&chip->dev);
err_get_device:
			module_put(chip->owner);
			return err;
		}
	}

	if (ops->read_waveform || ops->get_state) {
		/*
		 * Zero-initialize state because most drivers are unaware of
		 * .usage_power. The other members of state are supposed to be
		 * set by lowlevel drivers. We still initialize the whole
		 * structure for simplicity even though this might paper over
		 * faulty implementations of .get_state().
		 */
		struct pwm_state state = { 0, };

		err = pwm_get_state_hw(pwm, &state);
		if (!err)
			pwm->state = state;

		if (IS_ENABLED(CONFIG_PWM_DEBUG))
			pwm->last = pwm->state;
	}

	set_bit(PWMF_REQUESTED, &pwm->flags);
	pwm->label = label;

	return 0;
}

/**
 * pwm_request_from_chip() - request a PWM device relative to a PWM chip
 * @chip: PWM chip
 * @index: per-chip index of the PWM to request
 * @label: a literal description string of this PWM
 *
 * Returns: A pointer to the PWM device at the given index of the given PWM
 * chip. A negative error code is returned if the index is not valid for the
 * specified PWM chip or if the PWM device cannot be requested.
 */
static struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
						unsigned int index,
						const char *label)
{
	struct pwm_device *pwm;
	int err;

	if (!chip || index >= chip->npwm)
		return ERR_PTR(-EINVAL);

	guard(mutex)(&pwm_lock);

	pwm = &chip->pwms[index];

	err = pwm_device_request(pwm, label);
	if (err < 0)
		return ERR_PTR(err);

	return pwm;
}

struct pwm_device *
of_pwm_xlate_with_flags(struct pwm_chip *chip, const struct of_phandle_args *args)
{
	struct pwm_device *pwm;

	/* period in the second cell and flags in the third cell are optional */
	if (args->args_count < 1)
		return ERR_PTR(-EINVAL);

	pwm = pwm_request_from_chip(chip, args->args[0], NULL);
	if (IS_ERR(pwm))
		return pwm;

	if (args->args_count > 1)
		pwm->args.period = args->args[1];

	pwm->args.polarity = PWM_POLARITY_NORMAL;
	if (args->args_count > 2 && args->args[2] & PWM_POLARITY_INVERTED)
		pwm->args.polarity = PWM_POLARITY_INVERSED;

	return pwm;
}
EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags);

/*
 * This callback is used for PXA PWM chips that only have a single PWM line.
 * For such chips you could argue that passing the line number (i.e. the first
 * parameter in the common case) is useless as it's always zero. So compared to
 * the default xlate function of_pwm_xlate_with_flags() the first parameter is
 * the default period and the second are flags.
 *
 * Note that if #pwm-cells = <3>, the semantic is the same as for
 * of_pwm_xlate_with_flags() to allow converting the affected driver to
 * #pwm-cells = <3> without breaking the legacy binding.
 *
 * Don't use for new drivers.
 */
struct pwm_device *
of_pwm_single_xlate(struct pwm_chip *chip, const struct of_phandle_args *args)
{
	struct pwm_device *pwm;

	if (args->args_count >= 3)
		return of_pwm_xlate_with_flags(chip, args);

	pwm = pwm_request_from_chip(chip, 0, NULL);
	if (IS_ERR(pwm))
		return pwm;

	if (args->args_count > 0)
		pwm->args.period = args->args[0];

	pwm->args.polarity = PWM_POLARITY_NORMAL;
	if (args->args_count > 1 && args->args[1] & PWM_POLARITY_INVERTED)
		pwm->args.polarity = PWM_POLARITY_INVERSED;

	return pwm;
}
EXPORT_SYMBOL_GPL(of_pwm_single_xlate);

struct pwm_export {
	struct device pwm_dev;
	struct pwm_device *pwm;
	struct mutex lock;
	struct pwm_state suspend;
};

static inline struct pwm_chip *pwmchip_from_dev(struct device *pwmchip_dev)
{
	return container_of(pwmchip_dev, struct pwm_chip, dev);
}

static inline struct pwm_export *pwmexport_from_dev(struct device *pwm_dev)
{
	return container_of(pwm_dev, struct pwm_export, pwm_dev);
}

static inline struct pwm_device *pwm_from_dev(struct device *pwm_dev)
{
	struct pwm_export *export = pwmexport_from_dev(pwm_dev);

	return export->pwm;
}

static ssize_t period_show(struct device *pwm_dev,
			   struct device_attribute *attr,
			   char *buf)
{
	const struct pwm_device *pwm = pwm_from_dev(pwm_dev);
	struct pwm_state state;

	pwm_get_state(pwm, &state);

	return sysfs_emit(buf, "%llu\n", state.period);
}

static ssize_t period_store(struct device *pwm_dev,
			    struct device_attribute *attr,
			    const char *buf, size_t size)
{
	struct pwm_export *export = pwmexport_from_dev(pwm_dev);
	struct pwm_device *pwm = export->pwm;
	struct pwm_state state;
	u64 val;
	int ret;

	ret = kstrtou64(buf, 0, &val);
	if (ret)
		return ret;

	guard(mutex)(&export->lock);

	pwm_get_state(pwm, &state);
	state.period = val;
	ret = pwm_apply_might_sleep(pwm, &state);

	return ret ? : size;
}

static ssize_t duty_cycle_show(struct device *pwm_dev,
			       struct device_attribute *attr,
			       char *buf)
{
	const struct pwm_device *pwm = pwm_from_dev(pwm_dev);
	struct pwm_state state;

	pwm_get_state(pwm, &state);

	return sysfs_emit(buf, "%llu\n", state.duty_cycle);
}

static ssize_t duty_cycle_store(struct device *pwm_dev,
				struct device_attribute *attr,
				const char *buf, size_t size)
{
	struct pwm_export *export = pwmexport_from_dev(pwm_dev);
	struct pwm_device *pwm = export->pwm;
	struct pwm_state state;
	u64 val;
	int ret;

	ret = kstrtou64(buf, 0, &val);
	if (ret)
		return ret;

	guard(mutex)(&export->lock);

	pwm_get_state(pwm, &state);
	state.duty_cycle = val;
	ret = pwm_apply_might_sleep(pwm, &state);

	return ret ? : size;
}

static ssize_t enable_show(struct device *pwm_dev,
			   struct device_attribute *attr,
			   char *buf)
{
	const struct pwm_device *pwm = pwm_from_dev(pwm_dev);
	struct pwm_state state;

	pwm_get_state(pwm, &state);

	return sysfs_emit(buf, "%d\n", state.enabled);
}

static ssize_t enable_store(struct device *pwm_dev,
			    struct device_attribute *attr,
			    const char *buf, size_t size)
{
	struct pwm_export *export = pwmexport_from_dev(pwm_dev);
	struct pwm_device *pwm = export->pwm;
	struct pwm_state state;
	int val, ret;

	ret = kstrtoint(buf, 0, &val);
	if (ret)
		return ret;

	guard(mutex)(&export->lock);

	pwm_get_state(pwm, &state);

	switch (val) {
	case 0:
		state.enabled = false;
		break;
	case 1:
		state.enabled = true;
		break;
	default:
		return -EINVAL;
	}

	ret = pwm_apply_might_sleep(pwm, &state);

	return ret ? : size;
}

static ssize_t polarity_show(struct device *pwm_dev,
			     struct device_attribute *attr,
			     char *buf)
{
	const struct pwm_device *pwm = pwm_from_dev(pwm_dev);
	const char *polarity = "unknown";
	struct pwm_state state;

	pwm_get_state(pwm, &state);

	switch (state.polarity) {
	case PWM_POLARITY_NORMAL:
		polarity = "normal";
		break;

	case PWM_POLARITY_INVERSED:
		polarity = "inversed";
		break;
	}

	return sysfs_emit(buf, "%s\n", polarity);
}

static ssize_t polarity_store(struct device *pwm_dev,
			      struct device_attribute *attr,
			      const char *buf, size_t size)
{
	struct pwm_export *export = pwmexport_from_dev(pwm_dev);
	struct pwm_device *pwm = export->pwm;
	enum pwm_polarity polarity;
	struct pwm_state state;
	int ret;

	if (sysfs_streq(buf, "normal"))
		polarity = PWM_POLARITY_NORMAL;
	else if (sysfs_streq(buf, "inversed"))
		polarity = PWM_POLARITY_INVERSED;
	else
		return -EINVAL;

	guard(mutex)(&export->lock);

	pwm_get_state(pwm, &state);
	state.polarity = polarity;
	ret = pwm_apply_might_sleep(pwm, &state);

	return ret ? : size;
}

static ssize_t capture_show(struct device *pwm_dev,
			    struct device_attribute *attr,
			    char *buf)
{
	struct pwm_device *pwm = pwm_from_dev(pwm_dev);
	struct pwm_capture result;
	int ret;

	ret = pwm_capture(pwm, &result, jiffies_to_msecs(HZ));
	if (ret)
		return ret;

	return sysfs_emit(buf, "%u %u\n", result.period, result.duty_cycle);
}

static DEVICE_ATTR_RW(period);
static DEVICE_ATTR_RW(duty_cycle);
static DEVICE_ATTR_RW(enable);
static DEVICE_ATTR_RW(polarity);
static DEVICE_ATTR_RO(capture);

static struct attribute *pwm_attrs[] = {
	&dev_attr_period.attr,
	&dev_attr_duty_cycle.attr,
	&dev_attr_enable.attr,
	&dev_attr_polarity.attr,
	&dev_attr_capture.attr,
	NULL
};
ATTRIBUTE_GROUPS(pwm);

static void pwm_export_release(struct device *pwm_dev)
{
	struct pwm_export *export = pwmexport_from_dev(pwm_dev);

	kfree(export);
}

static int pwm_export_child(struct device *pwmchip_dev, struct pwm_device *pwm)
{
	struct pwm_export *export;
	char *pwm_prop[2];
	int ret;

	if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
		return -EBUSY;

	export = kzalloc_obj(*export);
	if (!export) {
		clear_bit(PWMF_EXPORTED, &pwm->flags);
		return -ENOMEM;
	}

	export->pwm = pwm;
	mutex_init(&export->lock);

	export->pwm_dev.release = pwm_export_release;
	export->pwm_dev.parent = pwmchip_dev;
	export->pwm_dev.devt = MKDEV(0, 0);
	export->pwm_dev.groups = pwm_groups;
	dev_set_name(&export->pwm_dev, "pwm%u", pwm->hwpwm);

	ret = device_register(&export->pwm_dev);
	if (ret) {
		clear_bit(PWMF_EXPORTED, &pwm->flags);
		put_device(&export->pwm_dev);
		export = NULL;
		return ret;
	}
	pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm);
	pwm_prop[1] = NULL;
	kobject_uevent_env(&pwmchip_dev->kobj, KOBJ_CHANGE, pwm_prop);
	kfree(pwm_prop[0]);

	return 0;
}

static int pwm_unexport_match(struct device *pwm_dev, const void *data)
{
	return pwm_from_dev(pwm_dev) == data;
}

static int pwm_unexport_child(struct device *pwmchip_dev, struct pwm_device *pwm)
{
	struct device *pwm_dev;
	char *pwm_prop[2];

	if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
		return -ENODEV;

	pwm_dev = device_find_child(pwmchip_dev, pwm, pwm_unexport_match);
	if (!pwm_dev)
		return -ENODEV;

	pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm);
	pwm_prop[1] = NULL;
	kobject_uevent_env(&pwmchip_dev->kobj, KOBJ_CHANGE, pwm_prop);
	kfree(pwm_prop[0]);

	/* for device_find_child() */
	put_device(pwm_dev);
	device_unregister(pwm_dev);
	pwm_put(pwm);

	return 0;
}

static ssize_t export_store(struct device *pwmchip_dev,
			    struct device_attribute *attr,
			    const char *buf, size_t len)
{
	struct pwm_chip *chip = pwmchip_from_dev(pwmchip_dev);
	struct pwm_device *pwm;
	unsigned int hwpwm;
	int ret;

	ret = kstrtouint(buf, 0, &hwpwm);
	if (ret < 0)
		return ret;

	if (hwpwm >= chip->npwm)
		return -ENODEV;

	pwm = pwm_request_from_chip(chip, hwpwm, "sysfs");
	if (IS_ERR(pwm))
		return PTR_ERR(pwm);

	ret = pwm_export_child(pwmchip_dev, pwm);
	if (ret < 0)
		pwm_put(pwm);

	return ret ? : len;
}
static DEVICE_ATTR_WO(export);

static ssize_t unexport_store(struct device *pwmchip_dev,
			      struct device_attribute *attr,
			      const char *buf, size_t len)
{
	struct pwm_chip *chip = pwmchip_from_dev(pwmchip_dev);
	unsigned int hwpwm;
	int ret;

	ret = kstrtouint(buf, 0, &hwpwm);
	if (ret < 0)
		return ret;

	if (hwpwm >= chip->npwm)
		return -ENODEV;

	ret = pwm_unexport_child(pwmchip_dev, &chip->pwms[hwpwm]);

	return ret ? : len;
}
static DEVICE_ATTR_WO(unexport);

static ssize_t npwm_show(struct device *pwmchip_dev, struct device_attribute *attr,
			 char *buf)
{
	const struct pwm_chip *chip = pwmchip_from_dev(pwmchip_dev);

	return sysfs_emit(buf, "%u\n", chip->npwm);
}
static DEVICE_ATTR_RO(npwm);

static struct attribute *pwm_chip_attrs[] = {
	&dev_attr_export.attr,
	&dev_attr_unexport.attr,
	&dev_attr_npwm.attr,
	NULL,
};
ATTRIBUTE_GROUPS(pwm_chip);

/* takes export->lock on success */
static struct pwm_export *pwm_class_get_state(struct device *pwmchip_dev,
					      struct pwm_device *pwm,
					      struct pwm_state *state)
{
	struct device *pwm_dev;
	struct pwm_export *export;

	if (!test_bit(PWMF_EXPORTED, &pwm->flags))
		return NULL;

	pwm_dev = device_find_child(pwmchip_dev, pwm, pwm_unexport_match);
	if (!pwm_dev)
		return NULL;

	export = pwmexport_from_dev(pwm_dev);
	put_device(pwm_dev);	/* for device_find_child() */

	mutex_lock(&export->lock);
	pwm_get_state(pwm, state);

	return export;
}

static int pwm_class_apply_state(struct pwm_export *export,
				 struct pwm_device *pwm,
				 struct pwm_state *state)
{
	int ret = pwm_apply_might_sleep(pwm, state);

	/* release lock taken in pwm_class_get_state */
	mutex_unlock(&export->lock);

	return ret;
}

static int pwm_class_resume_npwm(struct device *pwmchip_dev, unsigned int npwm)
{
	struct pwm_chip *chip = pwmchip_from_dev(pwmchip_dev);
	unsigned int i;
	int ret = 0;

	for (i = 0; i < npwm; i++) {
		struct pwm_device *pwm = &chip->pwms[i];
		struct pwm_state state;
		struct pwm_export *export;

		export = pwm_class_get_state(pwmchip_dev, pwm, &state);
		if (!export)
			continue;

		/* If pwmchip was not enabled before suspend, do nothing. */
		if (!export->suspend.enabled) {
			/* release lock taken in pwm_class_get_state */
			mutex_unlock(&export->lock);
			continue;
		}

		state.enabled = export->suspend.enabled;
		ret = pwm_class_apply_state(export, pwm, &state);
		if (ret < 0)
			break;
	}

	return ret;
}

static int pwm_class_suspend(struct device *pwmchip_dev)
{
	struct pwm_chip *chip = pwmchip_from_dev(pwmchip_dev);
	unsigned int i;
	int ret = 0;

	for (i = 0; i < chip->npwm; i++) {
		struct pwm_device *pwm = &chip->pwms[i];
		struct pwm_state state;
		struct pwm_export *export;

		export = pwm_class_get_state(pwmchip_dev, pwm, &state);
		if (!export)
			continue;

		/*
		 * If pwmchip was not enabled before suspend, save
		 * state for resume time and do nothing else.
		 */
		export->suspend = state;
		if (!state.enabled) {
			/* release lock taken in pwm_class_get_state */
			mutex_unlock(&export->lock);
			continue;
		}

		state.enabled = false;
		ret = pwm_class_apply_state(export, pwm, &state);
		if (ret < 0) {
			/*
			 * roll back the PWM devices that were disabled by
			 * this suspend function.
			 */
			pwm_class_resume_npwm(pwmchip_dev, i);
			break;
		}
	}

	return ret;
}

static int pwm_class_resume(struct device *pwmchip_dev)
{
	struct pwm_chip *chip = pwmchip_from_dev(pwmchip_dev);

	return pwm_class_resume_npwm(pwmchip_dev, chip->npwm);
}

static DEFINE_SIMPLE_DEV_PM_OPS(pwm_class_pm_ops, pwm_class_suspend, pwm_class_resume);

static struct class pwm_class = {
	.name = "pwm",
	.dev_groups = pwm_chip_groups,
	.pm = pm_sleep_ptr(&pwm_class_pm_ops),
};

static void pwmchip_sysfs_unexport(struct pwm_chip *chip)
{
	unsigned int i;

	for (i = 0; i < chip->npwm; i++) {
		struct pwm_device *pwm = &chip->pwms[i];

		if (test_bit(PWMF_EXPORTED, &pwm->flags))
			pwm_unexport_child(&chip->dev, pwm);
	}
}

#define PWMCHIP_ALIGN ARCH_DMA_MINALIGN

static void *pwmchip_priv(struct pwm_chip *chip)
{
	return (void *)chip + ALIGN(struct_size(chip, pwms, chip->npwm), PWMCHIP_ALIGN);
}

/* This is the counterpart to pwmchip_alloc() */
void pwmchip_put(struct pwm_chip *chip)
{
	put_device(&chip->dev);
}
EXPORT_SYMBOL_GPL(pwmchip_put);

void pwmchip_release(struct device *pwmchip_dev)
{
	struct pwm_chip *chip = pwmchip_from_dev(pwmchip_dev);

	kfree(chip);
}
EXPORT_SYMBOL_GPL(pwmchip_release);

struct pwm_chip *pwmchip_alloc(struct device *parent, unsigned int npwm, size_t sizeof_priv)
{
	struct pwm_chip *chip;
	struct device *pwmchip_dev;
	size_t alloc_size;
	unsigned int i;

	alloc_size = size_add(ALIGN(struct_size(chip, pwms, npwm), PWMCHIP_ALIGN),
			      sizeof_priv);

	chip = kzalloc(alloc_size, GFP_KERNEL);
	if (!chip)
		return ERR_PTR(-ENOMEM);

	chip->npwm = npwm;
	chip->uses_pwmchip_alloc = true;
	chip->operational = false;

	pwmchip_dev = &chip->dev;
	device_initialize(pwmchip_dev);
	pwmchip_dev->class = &pwm_class;
	pwmchip_dev->parent = parent;
	pwmchip_dev->release = pwmchip_release;

	pwmchip_set_drvdata(chip, pwmchip_priv(chip));

	for (i = 0; i < chip->npwm; i++) {
		struct pwm_device *pwm = &chip->pwms[i];
		pwm->chip = chip;
		pwm->hwpwm = i;
	}

	return chip;
}
EXPORT_SYMBOL_GPL(pwmchip_alloc);

static void devm_pwmchip_put(void *data)
{
	struct pwm_chip *chip = data;

	pwmchip_put(chip);
}

struct pwm_chip *devm_pwmchip_alloc(struct device *parent, unsigned int npwm, size_t sizeof_priv)
{
	struct pwm_chip *chip;
	int ret;

	chip = pwmchip_alloc(parent, npwm, sizeof_priv);
	if (IS_ERR(chip))
		return chip;

	ret = devm_add_action_or_reset(parent, devm_pwmchip_put, chip);
	if (ret)
		return ERR_PTR(ret);

	return chip;
}
EXPORT_SYMBOL_GPL(devm_pwmchip_alloc);

static void of_pwmchip_add(struct pwm_chip *chip)
{
	if (!pwmchip_parent(chip) || !pwmchip_parent(chip)->of_node)
		return;

	if (!chip->of_xlate)
		chip->of_xlate = of_pwm_xlate_with_flags;

	of_node_get(pwmchip_parent(chip)->of_node);
}

static void of_pwmchip_remove(struct pwm_chip *chip)
{
	if (pwmchip_parent(chip))
		of_node_put(pwmchip_parent(chip)->of_node);
}

static bool pwm_ops_check(const struct pwm_chip *chip)
{
	const struct pwm_ops *ops = chip->ops;

	if (ops->write_waveform) {
		if (!ops->round_waveform_tohw ||
		    !ops->round_waveform_fromhw)
			return false;

		if (PWM_WFHWSIZE < ops->sizeof_wfhw) {
			dev_warn(pwmchip_parent(chip), "PWM_WFHWSIZE < %zu\n", ops->sizeof_wfhw);
			return false;
		}
	} else {
		if (!ops->apply)
			return false;

		if (IS_ENABLED(CONFIG_PWM_DEBUG) && !ops->get_state)
			dev_warn(pwmchip_parent(chip),
				 "Please implement the .get_state() callback\n");
	}

	return true;
}

static struct device_link *pwm_device_link_add(struct device *dev,
					       struct pwm_device *pwm)
{
	struct device_link *dl;

	if (!dev) {
		/*
		 * No device for the PWM consumer has been provided. It may
		 * impact the PM sequence ordering: the PWM supplier may get
		 * suspended before the consumer.
		 */
		dev_warn(pwmchip_parent(pwm->chip),
			 "No consumer device specified to create a link to\n");
		return NULL;
	}

	dl = device_link_add(dev, pwmchip_parent(pwm->chip), DL_FLAG_AUTOREMOVE_CONSUMER);
	if (!dl) {
		dev_err(dev, "failed to create device link to %s\n",
			dev_name(pwmchip_parent(pwm->chip)));
		return ERR_PTR(-EINVAL);
	}

	return dl;
}

static struct pwm_chip *fwnode_to_pwmchip(struct fwnode_handle *fwnode)
{
	struct pwm_chip *chip;
	unsigned long id, tmp;

	guard(mutex)(&pwm_lock);

	idr_for_each_entry_ul(&pwm_chips, chip, tmp, id)
		if (pwmchip_parent(chip) && device_match_fwnode(pwmchip_parent(chip), fwnode))
			return chip;

	return ERR_PTR(-EPROBE_DEFER);
}

/**
 * of_pwm_get() - request a PWM via the PWM framework
 * @dev: device for PWM consumer
 * @np: device node to get the PWM from
 * @con_id: consumer name
 *
 * Returns the PWM device parsed from the phandle and index specified in the
 * "pwms" property of a device tree node or a negative error-code on failure.
 * Values parsed from the device tree are stored in the returned PWM device
 * object.
 *
 * If con_id is NULL, the first PWM device listed in the "pwms" property will
 * be requested. Otherwise the "pwm-names" property is used to do a reverse
 * lookup of the PWM index. This also means that the "pwm-names" property
 * becomes mandatory for devices that look up the PWM device via the con_id
 * parameter.
 *
 * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
 * error code on failure.
 */
static struct pwm_device *of_pwm_get(struct device *dev, struct device_node *np,
				     const char *con_id)
{
	struct pwm_device *pwm = NULL;
	struct of_phandle_args args;
	struct device_link *dl;
	struct pwm_chip *chip;
	int index = 0;
	int err;

	if (con_id) {
		index = of_property_match_string(np, "pwm-names", con_id);
		if (index < 0)
			return ERR_PTR(index);
	}

	err = of_parse_phandle_with_args_map(np, "pwms", "pwm", index, &args);
	if (err) {
		pr_err("%s(): can't parse \"pwms\" property\n", __func__);
		return ERR_PTR(err);
	}

	chip = fwnode_to_pwmchip(of_fwnode_handle(args.np));
	if (IS_ERR(chip)) {
		if (PTR_ERR(chip) != -EPROBE_DEFER)
			pr_err("%s(): PWM chip not found\n", __func__);

		pwm = ERR_CAST(chip);
		goto put;
	}

	pwm = chip->of_xlate(chip, &args);
	if (IS_ERR(pwm))
		goto put;

	dl = pwm_device_link_add(dev, pwm);
	if (IS_ERR(dl)) {
		/* of_xlate ended up calling pwm_request_from_chip() */
		pwm_put(pwm);
		pwm = ERR_CAST(dl);
		goto put;
	}

	/*
	 * If a consumer name was not given, try to look it up from the
	 * "pwm-names" property if it exists. Otherwise use the name of
	 * the user device node.
	 */
	if (!con_id) {
		err = of_property_read_string_index(np, "pwm-names", index,
						    &con_id);
		if (err < 0)
			con_id = np->name;
	}

	pwm->label = con_id;

put:
	of_node_put(args.np);

	return pwm;
}

/**
 * acpi_pwm_get() - request a PWM via parsing "pwms" property in ACPI
 * @fwnode: firmware node to get the "pwms" property from
 *
 * Returns the PWM device parsed from the fwnode and index specified in the
 * "pwms" property or a negative error-code on failure.
 * Values parsed from the device tree are stored in the returned PWM device
 * object.
 *
 * This is analogous to of_pwm_get() except con_id is not yet supported.
 * ACPI entries must look like
 * Package () {"pwms", Package ()
 *     { <PWM device reference>, <PWM index>, <PWM period> [, <PWM flags>]}}
 *
 * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
 * error code on failure.
 */
static struct pwm_device *acpi_pwm_get(const struct fwnode_handle *fwnode)
{
	struct pwm_device *pwm;
	struct fwnode_reference_args args;
	struct pwm_chip *chip;
	int ret;

	memset(&args, 0, sizeof(args));

	ret = __acpi_node_get_property_reference(fwnode, "pwms", 0, 3, &args);
	if (ret < 0)
		return ERR_PTR(ret);

	if (args.nargs < 2)
		return ERR_PTR(-EPROTO);

	chip = fwnode_to_pwmchip(args.fwnode);
	if (IS_ERR(chip))
		return ERR_CAST(chip);

	pwm = pwm_request_from_chip(chip, args.args[0], NULL);
	if (IS_ERR(pwm))
		return pwm;

	pwm->args.period = args.args[1];
	pwm->args.polarity = PWM_POLARITY_NORMAL;

	if (args.nargs > 2 && args.args[2] & PWM_POLARITY_INVERTED)
		pwm->args.polarity = PWM_POLARITY_INVERSED;

	return pwm;
}

static DEFINE_MUTEX(pwm_lookup_lock);
static LIST_HEAD(pwm_lookup_list);

/**
 * pwm_get() - look up and request a PWM device
 * @dev: device for PWM consumer
 * @con_id: consumer name
 *
 * Lookup is first attempted using DT. If the device was not instantiated from
 * a device tree, a PWM chip and a relative index is looked up via a table
 * supplied by board setup code (see pwm_add_table()).
 *
 * Once a PWM chip has been found the specified PWM device will be requested
 * and is ready to be used.
 *
 * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
 * error code on failure.
 */
struct pwm_device *pwm_get(struct device *dev, const char *con_id)
{
	const struct fwnode_handle *fwnode = dev ? dev_fwnode(dev) : NULL;
	const char *dev_id = dev ? dev_name(dev) : NULL;
	struct pwm_device *pwm;
	struct pwm_chip *chip;
	struct device_link *dl;
	unsigned int best = 0;
	struct pwm_lookup *p, *chosen = NULL;
	unsigned int match;
	int err;

	/* look up via DT first */
	if (is_of_node(fwnode))
		return of_pwm_get(dev, to_of_node(fwnode), con_id);

	/* then lookup via ACPI */
	if (is_acpi_node(fwnode)) {
		pwm = acpi_pwm_get(fwnode);
		if (!IS_ERR(pwm) || PTR_ERR(pwm) != -ENOENT)
			return pwm;
	}

	/*
	 * We look up the provider in the static table typically provided by
	 * board setup code. We first try to lookup the consumer device by
	 * name. If the consumer device was passed in as NULL or if no match
	 * was found, we try to find the consumer by directly looking it up
	 * by name.
	 *
	 * If a match is found, the provider PWM chip is looked up by name
	 * and a PWM device is requested using the PWM device per-chip index.
	 *
	 * The lookup algorithm was shamelessly taken from the clock
	 * framework:
	 *
	 * We do slightly fuzzy matching here:
	 *  An entry with a NULL ID is assumed to be a wildcard.
	 *  If an entry has a device ID, it must match
	 *  If an entry has a connection ID, it must match
	 * Then we take the most specific entry - with the following order
	 * of precedence: dev+con > dev only > con only.
	 */
	scoped_guard(mutex, &pwm_lookup_lock)
		list_for_each_entry(p, &pwm_lookup_list, list) {
			match = 0;

			if (p->dev_id) {
				if (!dev_id || strcmp(p->dev_id, dev_id))
					continue;

				match += 2;
			}

			if (p->con_id) {
				if (!con_id || strcmp(p->con_id, con_id))
					continue;

				match += 1;
			}

			if (match > best) {
				chosen = p;

				if (match != 3)
					best = match;
				else
					break;
			}
		}

	if (!chosen)
		return ERR_PTR(-ENODEV);

	chip = pwmchip_find_by_name(chosen->provider);

	/*
	 * If the lookup entry specifies a module, load the module and retry
	 * the PWM chip lookup. This can be used to work around driver load
	 * ordering issues if driver's can't be made to properly support the
	 * deferred probe mechanism.
	 */
	if (!chip && chosen->module) {
		err = request_module(chosen->module);
		if (err == 0)
			chip = pwmchip_find_by_name(chosen->provider);
	}

	if (!chip)
		return ERR_PTR(-EPROBE_DEFER);

	pwm = pwm_request_from_chip(chip, chosen->index, con_id ?: dev_id);
	if (IS_ERR(pwm))
		return pwm;

	dl = pwm_device_link_add(dev, pwm);
	if (IS_ERR(dl)) {
		pwm_put(pwm);
		return ERR_CAST(dl);
	}

	pwm->args.period = chosen->period;
	pwm->args.polarity = chosen->polarity;

	return pwm;
}
EXPORT_SYMBOL_GPL(pwm_get);

static void __pwm_put(struct pwm_device *pwm)
{
	struct pwm_chip *chip = pwm->chip;

	/*
	 * Trigger a warning if a consumer called pwm_put() twice.
	 * If the chip isn't operational, PWMF_REQUESTED was already cleared in
	 * pwmchip_remove(). So don't warn in this case.
	 */
	if (chip->operational && !test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) {
		pr_warn("PWM device already freed\n");
		return;
	}

	if (chip->operational && chip->ops->free)
		pwm->chip->ops->free(pwm->chip, pwm);

	pwm->label = NULL;

	put_device(&chip->dev);

	module_put(chip->owner);
}

/**
 * pwm_put() - release a PWM device
 * @pwm: PWM device
 */
void pwm_put(struct pwm_device *pwm)
{
	if (!pwm)
		return;

	guard(mutex)(&pwm_lock);

	__pwm_put(pwm);
}
EXPORT_SYMBOL_GPL(pwm_put);

static void devm_pwm_release(void *pwm)
{
	pwm_put(pwm);
}

/**
 * devm_pwm_get() - resource managed pwm_get()
 * @dev: device for PWM consumer
 * @con_id: consumer name
 *
 * This function performs like pwm_get() but the acquired PWM device will
 * automatically be released on driver detach.
 *
 * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
 * error code on failure.
 */
struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id)
{
	struct pwm_device *pwm;
	int ret;

	pwm = pwm_get(dev, con_id);
	if (IS_ERR(pwm))
		return pwm;

	ret = devm_add_action_or_reset(dev, devm_pwm_release, pwm);
	if (ret)
		return ERR_PTR(ret);

	return pwm;
}
EXPORT_SYMBOL_GPL(devm_pwm_get);

/**
 * devm_fwnode_pwm_get() - request a resource managed PWM from firmware node
 * @dev: device for PWM consumer
 * @fwnode: firmware node to get the PWM from
 * @con_id: consumer name
 *
 * Returns the PWM device parsed from the firmware node. See of_pwm_get() and
 * acpi_pwm_get() for a detailed description.
 *
 * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded
 * error code on failure.
 */
struct pwm_device *devm_fwnode_pwm_get(struct device *dev,
				       struct fwnode_handle *fwnode,
				       const char *con_id)
{
	struct pwm_device *pwm = ERR_PTR(-ENODEV);
	int ret;

	if (is_of_node(fwnode))
		pwm = of_pwm_get(dev, to_of_node(fwnode), con_id);
	else if (is_acpi_node(fwnode))
		pwm = acpi_pwm_get(fwnode);
	if (IS_ERR(pwm))
		return pwm;

	ret = devm_add_action_or_reset(dev, devm_pwm_release, pwm);
	if (ret)
		return ERR_PTR(ret);

	return pwm;
}
EXPORT_SYMBOL_GPL(devm_fwnode_pwm_get);

struct pwm_cdev_data {
	struct pwm_chip *chip;
	struct pwm_device *pwm[];
};

static int pwm_cdev_open(struct inode *inode, struct file *file)
{
	struct pwm_chip *chip = container_of(inode->i_cdev, struct pwm_chip, cdev);
	struct pwm_cdev_data *cdata;

	guard(mutex)(&pwm_lock);

	if (!chip->operational)
		return -ENXIO;

	cdata = kzalloc_flex(*cdata, pwm, chip->npwm);
	if (!cdata)
		return -ENOMEM;

	cdata->chip = chip;

	file->private_data = cdata;

	return nonseekable_open(inode, file);
}

static int pwm_cdev_release(struct inode *inode, struct file *file)
{
	struct pwm_cdev_data *cdata = file->private_data;
	unsigned int i;

	for (i = 0; i < cdata->chip->npwm; ++i) {
		struct pwm_device *pwm = cdata->pwm[i];

		if (pwm) {
			const char *label = pwm->label;

			pwm_put(cdata->pwm[i]);
			kfree(label);
		}
	}
	kfree(cdata);

	return 0;
}

static int pwm_cdev_request(struct pwm_cdev_data *cdata, unsigned int hwpwm)
{
	struct pwm_chip *chip = cdata->chip;

	if (hwpwm >= chip->npwm)
		return -EINVAL;

	if (!cdata->pwm[hwpwm]) {
		struct pwm_device *pwm = &chip->pwms[hwpwm];
		const char *label;
		int ret;

		label = kasprintf(GFP_KERNEL, "pwm-cdev (pid=%d)", current->pid);
		if (!label)
			return -ENOMEM;

		ret = pwm_device_request(pwm, label);
		if (ret < 0) {
			kfree(label);
			return ret;
		}

		cdata->pwm[hwpwm] = pwm;
	}

	return 0;
}

static int pwm_cdev_free(struct pwm_cdev_data *cdata, unsigned int hwpwm)
{
	struct pwm_chip *chip = cdata->chip;

	if (hwpwm >= chip->npwm)
		return -EINVAL;

	if (cdata->pwm[hwpwm]) {
		struct pwm_device *pwm = cdata->pwm[hwpwm];
		const char *label = pwm->label;

		__pwm_put(pwm);

		kfree(label);

		cdata->pwm[hwpwm] = NULL;
	}

	return 0;
}

static struct pwm_device *pwm_cdev_get_requested_pwm(struct pwm_cdev_data *cdata,
						     u32 hwpwm)
{
	struct pwm_chip *chip = cdata->chip;

	if (hwpwm >= chip->npwm)
		return ERR_PTR(-EINVAL);

	if (cdata->pwm[hwpwm])
		return cdata->pwm[hwpwm];

	return ERR_PTR(-EINVAL);
}

static long pwm_cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int ret = 0;
	struct pwm_cdev_data *cdata = file->private_data;
	struct pwm_chip *chip = cdata->chip;

	guard(mutex)(&pwm_lock);

	if (!chip->operational)
		return -ENODEV;

	switch (cmd) {
	case PWM_IOCTL_REQUEST:
		{
			unsigned int hwpwm = arg;

			return pwm_cdev_request(cdata, hwpwm);
		}

	case PWM_IOCTL_FREE:
		{
			unsigned int hwpwm = arg;

			return pwm_cdev_free(cdata, hwpwm);
		}

	case PWM_IOCTL_ROUNDWF:
		{
			struct pwmchip_waveform cwf;
			struct pwm_waveform wf;
			struct pwm_device *pwm;

			ret = copy_from_user(&cwf,
					     (struct pwmchip_waveform __user *)arg,
					     sizeof(cwf));
			if (ret)
				return -EFAULT;

			if (cwf.__pad != 0)
				return -EINVAL;

			pwm = pwm_cdev_get_requested_pwm(cdata, cwf.hwpwm);
			if (IS_ERR(pwm))
				return PTR_ERR(pwm);

			wf = (struct pwm_waveform) {
				.period_length_ns = cwf.period_length_ns,
				.duty_length_ns = cwf.duty_length_ns,
				.duty_offset_ns = cwf.duty_offset_ns,
			};

			ret = pwm_round_waveform_might_sleep(pwm, &wf);
			if (ret < 0)
				return ret;

			cwf = (struct pwmchip_waveform) {
				.hwpwm = cwf.hwpwm,
				.period_length_ns = wf.period_length_ns,
				.duty_length_ns = wf.duty_length_ns,
				.duty_offset_ns = wf.duty_offset_ns,
			};

			ret = copy_to_user((struct pwmchip_waveform __user *)arg,
					   &cwf, sizeof(cwf));
			return ret ? -EFAULT : 0;
		}

	case PWM_IOCTL_GETWF:
		{
			struct pwmchip_waveform cwf;
			struct pwm_waveform wf;
			struct pwm_device *pwm;

			ret = copy_from_user(&cwf,
					     (struct pwmchip_waveform __user *)arg,
					     sizeof(cwf));
			if (ret)
				return -EFAULT;

			if (cwf.__pad != 0)
				return -EINVAL;

			pwm = pwm_cdev_get_requested_pwm(cdata, cwf.hwpwm);
			if (IS_ERR(pwm))
				return PTR_ERR(pwm);

			ret = pwm_get_waveform_might_sleep(pwm, &wf);
			if (ret)
				return ret;

			cwf = (struct pwmchip_waveform) {
				.hwpwm = cwf.hwpwm,
				.period_length_ns = wf.period_length_ns,
				.duty_length_ns = wf.duty_length_ns,
				.duty_offset_ns = wf.duty_offset_ns,
			};

			ret = copy_to_user((struct pwmchip_waveform __user *)arg,
					   &cwf, sizeof(cwf));
			return ret ? -EFAULT : 0;
		}

	case PWM_IOCTL_SETROUNDEDWF:
	case PWM_IOCTL_SETEXACTWF:
		{
			struct pwmchip_waveform cwf;
			struct pwm_waveform wf;
			struct pwm_device *pwm;

			ret = copy_from_user(&cwf,
					     (struct pwmchip_waveform __user *)arg,
					     sizeof(cwf));
			if (ret)
				return -EFAULT;

			if (cwf.__pad != 0)
				return -EINVAL;

			wf = (struct pwm_waveform){
				.period_length_ns = cwf.period_length_ns,
				.duty_length_ns = cwf.duty_length_ns,
				.duty_offset_ns = cwf.duty_offset_ns,
			};

			if (!pwm_wf_valid(&wf))
				return -EINVAL;

			pwm = pwm_cdev_get_requested_pwm(cdata, cwf.hwpwm);
			if (IS_ERR(pwm))
				return PTR_ERR(pwm);

			ret = pwm_set_waveform_might_sleep(pwm, &wf,
							   cmd == PWM_IOCTL_SETEXACTWF);

			/*
			 * If userspace cares about rounding deviations it has
			 * to check the values anyhow, so simplify handling for
			 * them and don't signal uprounding. This matches the
			 * behaviour of PWM_IOCTL_ROUNDWF which also returns 0
			 * in that case.
			 */
			if (ret == 1)
				ret = 0;

			return ret;
		}

	default:
		return -ENOTTY;
	}
}

static const struct file_operations pwm_cdev_fileops = {
	.open = pwm_cdev_open,
	.release = pwm_cdev_release,
	.owner = THIS_MODULE,
	.unlocked_ioctl = pwm_cdev_ioctl,
};

static dev_t pwm_devt;

static int pwm_gpio_request(struct gpio_chip *gc, unsigned int offset)
{
	struct pwm_chip *chip = gpiochip_get_data(gc);
	struct pwm_device *pwm;

	pwm = pwm_request_from_chip(chip, offset, "pwm-gpio");
	if (IS_ERR(pwm))
		return PTR_ERR(pwm);

	return 0;
}

static void pwm_gpio_free(struct gpio_chip *gc, unsigned int offset)
{
	struct pwm_chip *chip = gpiochip_get_data(gc);

	pwm_put(&chip->pwms[offset]);
}

static int pwm_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
	return GPIO_LINE_DIRECTION_OUT;
}

static int pwm_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
{
	struct pwm_chip *chip = gpiochip_get_data(gc);
	struct pwm_device *pwm = &chip->pwms[offset];
	int ret;
	struct pwm_waveform wf = {
		.period_length_ns = 1,
	};

	ret = pwm_round_waveform_might_sleep(pwm, &wf);
	if (ret < 0)
		return ret;

	if (value)
		wf.duty_length_ns = wf.period_length_ns;
	else
		wf.duty_length_ns = 0;

	return pwm_set_waveform_might_sleep(pwm, &wf, true);
}

/**
 * __pwmchip_add() - register a new PWM chip
 * @chip: the PWM chip to add
 * @owner: reference to the module providing the chip.
 *
 * Register a new PWM chip. @owner is supposed to be THIS_MODULE, use the
 * pwmchip_add wrapper to do this right.
 *
 * Returns: 0 on success or a negative error code on failure.
 */
int __pwmchip_add(struct pwm_chip *chip, struct module *owner)
{
	int ret;

	if (!chip || !pwmchip_parent(chip) || !chip->ops || !chip->npwm)
		return -EINVAL;

	/*
	 * a struct pwm_chip must be allocated using (devm_)pwmchip_alloc,
	 * otherwise the embedded struct device might disappear too early
	 * resulting in memory corruption.
	 * Catch drivers that were not converted appropriately.
	 */
	if (!chip->uses_pwmchip_alloc)
		return -EINVAL;

	if (!pwm_ops_check(chip))
		return -EINVAL;

	chip->owner = owner;

	if (chip->atomic)
		spin_lock_init(&chip->atomic_lock);
	else
		mutex_init(&chip->nonatomic_lock);

	guard(mutex)(&pwm_lock);

	ret = idr_alloc(&pwm_chips, chip, 0, 0, GFP_KERNEL);
	if (ret < 0)
		return ret;

	chip->id = ret;

	dev_set_name(&chip->dev, "pwmchip%u", chip->id);

	if (IS_ENABLED(CONFIG_OF))
		of_pwmchip_add(chip);

	scoped_guard(pwmchip, chip)
		chip->operational = true;

	if (chip->ops->write_waveform) {
		if (chip->id < PWM_MINOR_COUNT)
			chip->dev.devt = MKDEV(MAJOR(pwm_devt), chip->id);
		else
			dev_warn(&chip->dev, "chip id too high to create a chardev\n");
	}

	cdev_init(&chip->cdev, &pwm_cdev_fileops);
	chip->cdev.owner = owner;

	ret = cdev_device_add(&chip->cdev, &chip->dev);
	if (ret)
		goto err_device_add;

	if (IS_ENABLED(CONFIG_PWM_PROVIDE_GPIO) && chip->ops->write_waveform) {
		struct device *parent = pwmchip_parent(chip);

		chip->gpio = (typeof(chip->gpio)){
			.label = dev_name(parent),
			.parent = parent,
			.request = pwm_gpio_request,
			.free = pwm_gpio_free,
			.get_direction = pwm_gpio_get_direction,
			.set = pwm_gpio_set,
			.base = -1,
			.ngpio = chip->npwm,
			.can_sleep = true,
		};

		ret = gpiochip_add_data(&chip->gpio, chip);
		if (ret)
			goto err_gpiochip_add;
	}

	return 0;

err_gpiochip_add:

	cdev_device_del(&chip->cdev, &chip->dev);
err_device_add:

	scoped_guard(pwmchip, chip)
		chip->operational = false;

	if (IS_ENABLED(CONFIG_OF))
		of_pwmchip_remove(chip);

	idr_remove(&pwm_chips, chip->id);

	return ret;
}
EXPORT_SYMBOL_GPL(__pwmchip_add);

/**
 * pwmchip_remove() - remove a PWM chip
 * @chip: the PWM chip to remove
 *
 * Removes a PWM chip.
 */
void pwmchip_remove(struct pwm_chip *chip)
{
	if (IS_ENABLED(CONFIG_PWM_PROVIDE_GPIO) && chip->ops->write_waveform)
		gpiochip_remove(&chip->gpio);

	pwmchip_sysfs_unexport(chip);

	scoped_guard(mutex, &pwm_lock) {
		unsigned int i;

		scoped_guard(pwmchip, chip)
			chip->operational = false;

		for (i = 0; i < chip->npwm; ++i) {
			struct pwm_device *pwm = &chip->pwms[i];

			if (test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) {
				dev_warn(&chip->dev, "Freeing requested PWM #%u\n", i);
				if (pwm->chip->ops->free)
					pwm->chip->ops->free(pwm->chip, pwm);
			}
		}

		if (IS_ENABLED(CONFIG_OF))
			of_pwmchip_remove(chip);

		idr_remove(&pwm_chips, chip->id);
	}

	cdev_device_del(&chip->cdev, &chip->dev);
}
EXPORT_SYMBOL_GPL(pwmchip_remove);

static void devm_pwmchip_remove(void *data)
{
	struct pwm_chip *chip = data;

	pwmchip_remove(chip);
}

int __devm_pwmchip_add(struct device *dev, struct pwm_chip *chip, struct module *owner)
{
	int ret;

	ret = __pwmchip_add(chip, owner);
	if (ret)
		return ret;

	return devm_add_action_or_reset(dev, devm_pwmchip_remove, chip);
}
EXPORT_SYMBOL_GPL(__devm_pwmchip_add);

/**
 * pwm_add_table() - register PWM device consumers
 * @table: array of consumers to register
 * @num: number of consumers in table
 */
void pwm_add_table(struct pwm_lookup *table, size_t num)
{
	guard(mutex)(&pwm_lookup_lock);

	while (num--) {
		list_add_tail(&table->list, &pwm_lookup_list);
		table++;
	}
}

/**
 * pwm_remove_table() - unregister PWM device consumers
 * @table: array of consumers to unregister
 * @num: number of consumers in table
 */
void pwm_remove_table(struct pwm_lookup *table, size_t num)
{
	guard(mutex)(&pwm_lookup_lock);

	while (num--) {
		list_del(&table->list);
		table++;
	}
}

static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
{
	unsigned int i;

	for (i = 0; i < chip->npwm; i++) {
		struct pwm_device *pwm = &chip->pwms[i];
		struct pwm_state state;
		int err;

		pwm_get_state(pwm, &state);

		seq_printf(s, " pwm-%-3d (%-20.20s):", i, pwm->label);

		if (test_bit(PWMF_REQUESTED, &pwm->flags))
			seq_puts(s, " requested");

		seq_putc(s, '\n');

		seq_printf(s, "  requested configuration: %3sabled, %llu/%llu ns, %s polarity",
			   state.enabled ? "en" : "dis", state.duty_cycle, state.period,
			   state.polarity ? "inverse" : "normal");
		if (state.usage_power)
			seq_puts(s, ", usage_power");
		seq_putc(s, '\n');

		if (pwmchip_supports_waveform(chip)) {
			struct pwm_waveform wf;

			err = pwm_get_waveform_might_sleep(pwm, &wf);
			if (!err)
				seq_printf(s, "  actual configuration: %lld/%lld [+%lld]",
					   wf.duty_length_ns, wf.period_length_ns, wf.duty_offset_ns);
			else
				seq_printf(s, "  actual configuration: read out error: %pe\n", ERR_PTR(err));
		} else {
			struct pwm_state hwstate;

			err = pwm_get_state_hw(pwm, &hwstate);
			if (!err)
				seq_printf(s, "  actual configuration:    %3sabled, %llu/%llu ns, %s polarity",
					   hwstate.enabled ? "en" : "dis", hwstate.duty_cycle, hwstate.period,
					   hwstate.polarity ? "inverse" : "normal");
			else
				seq_printf(s, "  actual configuration: read out error: %pe", ERR_PTR(err));
		}

		seq_putc(s, '\n');
	}
}

static void *pwm_seq_start(struct seq_file *s, loff_t *pos)
{
	unsigned long id = *pos;
	void *ret;

	mutex_lock(&pwm_lock);
	s->private = "";

	ret = idr_get_next_ul(&pwm_chips, &id);
	*pos = id;
	return ret;
}

static void *pwm_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
	unsigned long id = *pos + 1;
	void *ret;

	s->private = "\n";

	ret = idr_get_next_ul(&pwm_chips, &id);
	*pos = id;
	return ret;
}

static void pwm_seq_stop(struct seq_file *s, void *v)
{
	mutex_unlock(&pwm_lock);
}

static int pwm_seq_show(struct seq_file *s, void *v)
{
	struct pwm_chip *chip = v;

	seq_printf(s, "%s%u: %s/%s, npwm: %u\n",
		   (char *)s->private, chip->id,
		   pwmchip_parent(chip)->bus ? pwmchip_parent(chip)->bus->name : "no-bus",
		   dev_name(pwmchip_parent(chip)), chip->npwm);

	pwm_dbg_show(chip, s);

	return 0;
}

static const struct seq_operations pwm_debugfs_sops = {
	.start = pwm_seq_start,
	.next = pwm_seq_next,
	.stop = pwm_seq_stop,
	.show = pwm_seq_show,
};

DEFINE_SEQ_ATTRIBUTE(pwm_debugfs);

static int __init pwm_init(void)
{
	int ret;

	ret = alloc_chrdev_region(&pwm_devt, 0, PWM_MINOR_COUNT, "pwm");
	if (ret) {
		pr_err("Failed to initialize chrdev region for PWM usage\n");
		return ret;
	}

	ret = class_register(&pwm_class);
	if (ret) {
		pr_err("Failed to initialize PWM class (%pe)\n", ERR_PTR(ret));
		unregister_chrdev_region(pwm_devt, 256);
		return ret;
	}

	if (IS_ENABLED(CONFIG_DEBUG_FS))
		debugfs_create_file("pwm", 0444, NULL, NULL, &pwm_debugfs_fops);

	return 0;
}
subsys_initcall(pwm_init);
