All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Anderson <sean.anderson@seco.com>
To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Cc: linux-pwm@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Emil Lenngren <emil.lenngren@gmail.com>,
	michal.simek@xilinx.com, Alvaro Gamez <alvaro.gamez@hazent.com>,
	Thierry Reding <thierry.reding@gmail.com>,
	kernel@pengutronix.de, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v4 3/3] pwm: Add support for Xilinx AXI Timer
Date: Tue, 29 Jun 2021 14:01:31 -0400	[thread overview]
Message-ID: <a4943aa5-956c-1820-3489-994f0812c3a7@seco.com> (raw)
In-Reply-To: <20210629083144.53onthkcchbk73lo@pengutronix.de>



On 6/29/21 4:31 AM, Uwe Kleine-König wrote:
 > Hello Sean,
 >
 > On Mon, Jun 28, 2021 at 01:41:43PM -0400, Sean Anderson wrote:
 >> On 6/28/21 1:20 PM, Uwe Kleine-König wrote:
 >> > On Mon, Jun 28, 2021 at 12:35:19PM -0400, Sean Anderson wrote:
 >> >> On 6/28/21 12:24 PM, Uwe Kleine-König wrote:
 >> >> > On Mon, Jun 28, 2021 at 11:50:33AM -0400, Sean Anderson wrote:
 >> >> > > On 6/27/21 2:19 PM, Uwe Kleine-König wrote:
 >> >> > > > On Fri, Jun 25, 2021 at 01:46:26PM -0400, Sean Anderson wrote:
 >> >> > > > > So for the moment, why not give an error? This will be legal code both
 >> >> > > > > now and after round_state is implemented.
 >> >> > > >
 >> >> > > > The problem is where to draw the line. To stay with your example: If a
 >> >> > > > request for period = 150 ns comes in, and let X be the biggest period <=
 >> >> > > > 150 ns that the hardware can configure. For which values of X should an
 >> >> > > > error be returned and for which values the setting should be
 >> >> > > > implemented.
 >> >> > > >
 >> >> > > > In my eyes the only sensible thing to implement here is to tell the
 >> >> > > > consumer about X and let it decide if it's good enough. If you have a
 >> >> > > > better idea let me hear about it.
 >> >> > >
 >> >> > > Sure. And I think it's ok to tell the consumer that X is the best we can
 >> >> > > do. But if they go along and request an unconfigurable state anyway, we
 >> >> > > should tell them as much.
 >> >> >
 >> >> > I have the impression you didn't understand where I see the problem. If
 >> >> > you request 150 ns and the controller can only do 149 ns (or 149.6667 ns)
 >> >> > should we refuse? If yes: This is very unusable, e.g. the led-pwm driver
 >> >> > expects that it can configure the duty_cycle in 1/256 steps of the
 >> >> > period, and then maybe only steps 27 and 213 of the 256 possible steps
 >> >> > work. (This example doesn't really match because the led-pwm driver
 >> >> > varies duty_cycle and not period, but the principle becomes clear I
 >> >> > assume.) If no: Should we accept 151 ns? Isn't that ridiculous?
 >> >>
 >> >> I am fine with this sort of rounding. The part I take issue with is when
 >> >> the consumer requests (e.g.) a 10ns period, but the best we can do is
 >> >> 20ns. Or at the other end if they request a 4s period but the best we
 >> >> can do is 2s. Here, there is no obvious way to round it, so I think we
 >> >> should just say "come back with a reasonable period" and let whoever
 >> >> wrote the device tree pick a better period.
 >> >
 >> > Note that giving ridiculus examples is easy, but this doesn't help to
 >> > actually implement something sensible. Please tell us for your example
 >> > where the driver can only implement 20 ns what is the smallest requested
 >> > period the driver should accept.
 >>
 >> 20ns :)
 >>
 >> In the case of this device, that would result in 0% duty cycle with a
 >> 100MHz input. So the smallest reasonable period is 30ns with a duty
 >> cycle of 20ns.
 >
 > I took the time to understand the hardware a bit better, also to be able
 > to reply to your formulae below. So to recap (and simplify slightly
 > assuming TCSR_UDT = 1):
 >
 >
 >                TLR0 + 2
 >   period     = --------
 >                clkrate
 >
 >                TLR1 + 2
 >   duty_cycle = -------- if TLR1 < TLR0, else 0
 >                clkrate
 >
 >
 > where TLRx has the range [0..0xffffffff] (for some devices the range is
 > smaller). So clkrate seems to be 100 MHz?

On my system, yes.

 >
 >> >> > > IMO, this is the best way to prevent surprising results in the API.
 >> >> >
 >> >> > I think it's not possible in practise to refuse "near" misses and every
 >> >> > definition of "near" is in some case ridiculous. Also if you consider
 >> >> > the pwm_round_state() case you don't want to refuse any request to tell
 >> >> > as much as possible about your controller's capabilities. And then it's
 >> >> > straight forward to let apply behave in the same way to keep complexity
 >> >> > low.
 >> >> >
 >> >> > > The real issue here is that it is impossible to determine the correct
 >> >> > > way to round the PWM a priori, and in particular, without considering
 >> >> > > both duty_cycle and period. If a consumer requests very small
 >> >> > > period/duty cycle which we cannot produce, how should it be rounded?
 >> >> >
 >> >> > Yeah, because there is no obviously right one, I picked one that is as
 >> >> > wrong as the other possibilities but is easy to work with.
 >> >> >
 >> >> > > Should we just set TLR0=1 and TLR1=0 to give them 66% duty cycle with
 >> >> > > the least period? Or should we try and increase the period to better
 >> >> > > approximate the % duty cycle? And both of these decisions must be made
 >> >> > > knowing both parameters. We cannot (for example) just always round up,
 >> >> > > since we may produce a configuration with TLR0 == TLR1, which would
 >> >> > > produce 0% duty cycle instead of whatever was requested. Rounding rate
 >> >> > > will introduce significant complexity into the driver. Most of the time
 >> >> > > if a consumer requests an invalid rate, it is due to misconfiguration
 >> >> > > which is best solved by fixing the configuration.
 >> >> >
 >> >> > In the first step pick the biggest period not bigger than the requested
 >> >> > and then pick the biggest duty cycle that is not bigger than the
 >> >> > requested and that can be set with the just picked period. That is the
 >> >> > behaviour that all new drivers should do. This is somewhat arbitrary but
 >> >> > after quite some thought the most sensible in my eyes.
 >> >>
 >> >> And if there are no periods smaller than the requested period?
 >> >
 >> > Then return -ERANGE.
 >>
 >> Ok, so instead of
 >>
 >> 	if (cycles < 2 || cycles > priv->max + 2)
 >> 		return -ERANGE;
 >>
 >> you would prefer
 >>
 >> 	if (cycles < 2)
 >> 		return -ERANGE;
 >> 	else if (cycles > priv->max + 2)
 >> 		cycles = priv->max;
 >
 > The actual calculation is a bit harder to handle TCSR_UDT = 0 but in
 > principle, yes, but see below.
 >
 >> But if we do the above clamping for TLR0, then we have to recalculate
 >> the duty cycle for TLR1. Which I guess means doing something like
 >>
 >> 	ret = xilinx_timer_tlr_period(priv, &tlr0, tcsr0, state->period);
 >> 	if (ret)
 >> 		return ret;
 >>
 >> 	state->duty_cycle = mult_frac(state->duty_cycle,
 >> 				      xilinx_timer_get_period(priv, tlr0, tcsr0),
 >> 				      state->period);
 >>
 >> 	ret = xilinx_timer_tlr_period(priv, &tlr1, tcsr1, state->duty_cycle);
 >> 	if (ret)
 >> 		return ret;
 >
 > No, you need something like:
 >
 > 	/*
 > 	 * The multiplication cannot overflow as both priv_max and
 > 	 * NSEC_PER_SEC fit into an u32.
 > 	 */
 > 	max_period = div64_ul((u64)priv->max * NSEC_PER_SEC, clkrate);
 >
 > 	/* cap period to the maximal possible value */
 > 	if (state->period > max_period)
 > 		period = max_period;
 > 	else
 > 		period = state->period;
 >
 > 	/* cap duty_cycle to the maximal possible value */
 > 	if (state->duty_cycle > max_period)
 > 		duty_cycle = max_period;
 > 	else
 > 		duty_cycle = state->duty_cycle;

These caps may increase the % duty cycle. For example, consider when the
max is 100, and the user requests a period of 150 and a duty cycle of
75, for a % duty cycle of 50%. The current logic is equivalent to

	period = min(state->period, max_period);
	duty_cycle = min(state->duty_cycle, max_period);

Which will result in a period of 100 and a duty cycle of 75, for a 75%
duty cycle. Instead, we should do

	period = min(state->period, max_period);
	duty_cycle = mult_frac(state->duty_cycle, period, state->period);

which will result in a period of 100 and a duty cycle of 50.

 > 	period_cycles = period * clkrate / NSEC_PER_SEC;
 >
 > 	if (period_cycles < 2)
 > 		return -ERANGE;
 >
 > 	duty_cycles = duty_cycle * clkrate / NSEC_PER_SEC;
 >
 > 	/*
 > 	 * The hardware cannot emit a 100% relative duty cycle, if
 > 	 * duty_cycle >= period_cycles is programmed the hardware emits
 > 	 * a 0% relative duty cycle.
 > 	 */
 > 	if (duty_cycle == period_cycles)
 > 		duty_cycles = period_cycles - 1;
 >
 > 	/*
 > 	 * The hardware cannot emit a duty_cycle of one clk step, so
 > 	 * emit 0 instead.
 > 	 */
 > 	if (duty_cycles < 2)
 > 		duty_cycles = period_cycles;

Of course, the above may result in 100% duty cycle being rounded down to
0%. I feel like that is too big of a jump to ignore. Perhaps if we
cannot return -ERANGE we should at least dev_warn.

--Sean

 >> >> > > > > Perhaps I should add
 >> >> > > > >
 >> >> > > > > 	if (tlr0 <= tlr1)
 >> >> > > > > 		return -EINVAL;
 >> >> > > > >
 >> >> > > > > here to prevent accidentally getting 0% duty cycle.
 >> >> > > >
 >> >> > > > You can assume that duty_cycle <= period when .apply is called.
 >> >> > >
 >> >> > > Ok, I will only check for == then.
 >> >> >
 >> >> > You just have to pay attention to the case that you had to decrement
 >> >> > .period to the next possible value. Then .duty_cycle might be bigger
 >> >> > than the corrected period.
 >> >>
 >> >> This is specifically to prevent 100% duty cycle from turning into 0%. My
 >> >> current draft is
 >> >>
 >> >> 	/*
 >> >> 	 * If TLR0 == TLR1, then we will produce 0% duty cycle instead of 100%
 >> >> 	 * duty cycle. Try and reduce the high time to compensate. If we can't
 >> >> 	 * do that because the high time is already 0 cycles, then just error
 >> >> 	 * out.
 >> >> 	 */
 >> >> 	if (tlr0 == tlr1 && !tlr1--)
 >> >> 		return -EINVAL;
 >> >
 >> > If you follow my suggested policy this isn't an error and you should
 >> > yield the biggest duty_cycle here even if it is zero.
 >>
 >> So like this?
 >>
 >> 	if (tlr0 == tlr1) {
 >> 		if (tlr1)
 >> 			tlr1--;
 >> 		else if (tlr0 != priv->max)
 >> 			tlr0++;
 >> 		else
 >> 			return -ERANGE;
 >> 	}
 >
 > No, this is wrong as it configures a longer period than requested in
 > some cases.
 >
 >> And I would really appreciate if you could write up some documentation
 >> with common errors and how to handle them. It's not at all obvious to me
 >> what all the implications of the above guidelines are.
 >
 > Yes, I fully agree this should be documented and doing that is on my
 > todo list. Until I come around to do this, enabling PWM_DEBUG should
 > help you getting this right (assuming you test extensively and read the
 > resulting kernel messages).
 >
 > Best regards
 > Uwe
 >

WARNING: multiple messages have this Message-ID (diff)
From: Sean Anderson <sean.anderson@seco.com>
To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Cc: linux-pwm@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Emil Lenngren <emil.lenngren@gmail.com>,
	michal.simek@xilinx.com, Alvaro Gamez <alvaro.gamez@hazent.com>,
	Thierry Reding <thierry.reding@gmail.com>,
	kernel@pengutronix.de, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v4 3/3] pwm: Add support for Xilinx AXI Timer
Date: Tue, 29 Jun 2021 14:01:31 -0400	[thread overview]
Message-ID: <a4943aa5-956c-1820-3489-994f0812c3a7@seco.com> (raw)
In-Reply-To: <20210629083144.53onthkcchbk73lo@pengutronix.de>



On 6/29/21 4:31 AM, Uwe Kleine-König wrote:
 > Hello Sean,
 >
 > On Mon, Jun 28, 2021 at 01:41:43PM -0400, Sean Anderson wrote:
 >> On 6/28/21 1:20 PM, Uwe Kleine-König wrote:
 >> > On Mon, Jun 28, 2021 at 12:35:19PM -0400, Sean Anderson wrote:
 >> >> On 6/28/21 12:24 PM, Uwe Kleine-König wrote:
 >> >> > On Mon, Jun 28, 2021 at 11:50:33AM -0400, Sean Anderson wrote:
 >> >> > > On 6/27/21 2:19 PM, Uwe Kleine-König wrote:
 >> >> > > > On Fri, Jun 25, 2021 at 01:46:26PM -0400, Sean Anderson wrote:
 >> >> > > > > So for the moment, why not give an error? This will be legal code both
 >> >> > > > > now and after round_state is implemented.
 >> >> > > >
 >> >> > > > The problem is where to draw the line. To stay with your example: If a
 >> >> > > > request for period = 150 ns comes in, and let X be the biggest period <=
 >> >> > > > 150 ns that the hardware can configure. For which values of X should an
 >> >> > > > error be returned and for which values the setting should be
 >> >> > > > implemented.
 >> >> > > >
 >> >> > > > In my eyes the only sensible thing to implement here is to tell the
 >> >> > > > consumer about X and let it decide if it's good enough. If you have a
 >> >> > > > better idea let me hear about it.
 >> >> > >
 >> >> > > Sure. And I think it's ok to tell the consumer that X is the best we can
 >> >> > > do. But if they go along and request an unconfigurable state anyway, we
 >> >> > > should tell them as much.
 >> >> >
 >> >> > I have the impression you didn't understand where I see the problem. If
 >> >> > you request 150 ns and the controller can only do 149 ns (or 149.6667 ns)
 >> >> > should we refuse? If yes: This is very unusable, e.g. the led-pwm driver
 >> >> > expects that it can configure the duty_cycle in 1/256 steps of the
 >> >> > period, and then maybe only steps 27 and 213 of the 256 possible steps
 >> >> > work. (This example doesn't really match because the led-pwm driver
 >> >> > varies duty_cycle and not period, but the principle becomes clear I
 >> >> > assume.) If no: Should we accept 151 ns? Isn't that ridiculous?
 >> >>
 >> >> I am fine with this sort of rounding. The part I take issue with is when
 >> >> the consumer requests (e.g.) a 10ns period, but the best we can do is
 >> >> 20ns. Or at the other end if they request a 4s period but the best we
 >> >> can do is 2s. Here, there is no obvious way to round it, so I think we
 >> >> should just say "come back with a reasonable period" and let whoever
 >> >> wrote the device tree pick a better period.
 >> >
 >> > Note that giving ridiculus examples is easy, but this doesn't help to
 >> > actually implement something sensible. Please tell us for your example
 >> > where the driver can only implement 20 ns what is the smallest requested
 >> > period the driver should accept.
 >>
 >> 20ns :)
 >>
 >> In the case of this device, that would result in 0% duty cycle with a
 >> 100MHz input. So the smallest reasonable period is 30ns with a duty
 >> cycle of 20ns.
 >
 > I took the time to understand the hardware a bit better, also to be able
 > to reply to your formulae below. So to recap (and simplify slightly
 > assuming TCSR_UDT = 1):
 >
 >
 >                TLR0 + 2
 >   period     = --------
 >                clkrate
 >
 >                TLR1 + 2
 >   duty_cycle = -------- if TLR1 < TLR0, else 0
 >                clkrate
 >
 >
 > where TLRx has the range [0..0xffffffff] (for some devices the range is
 > smaller). So clkrate seems to be 100 MHz?

On my system, yes.

 >
 >> >> > > IMO, this is the best way to prevent surprising results in the API.
 >> >> >
 >> >> > I think it's not possible in practise to refuse "near" misses and every
 >> >> > definition of "near" is in some case ridiculous. Also if you consider
 >> >> > the pwm_round_state() case you don't want to refuse any request to tell
 >> >> > as much as possible about your controller's capabilities. And then it's
 >> >> > straight forward to let apply behave in the same way to keep complexity
 >> >> > low.
 >> >> >
 >> >> > > The real issue here is that it is impossible to determine the correct
 >> >> > > way to round the PWM a priori, and in particular, without considering
 >> >> > > both duty_cycle and period. If a consumer requests very small
 >> >> > > period/duty cycle which we cannot produce, how should it be rounded?
 >> >> >
 >> >> > Yeah, because there is no obviously right one, I picked one that is as
 >> >> > wrong as the other possibilities but is easy to work with.
 >> >> >
 >> >> > > Should we just set TLR0=1 and TLR1=0 to give them 66% duty cycle with
 >> >> > > the least period? Or should we try and increase the period to better
 >> >> > > approximate the % duty cycle? And both of these decisions must be made
 >> >> > > knowing both parameters. We cannot (for example) just always round up,
 >> >> > > since we may produce a configuration with TLR0 == TLR1, which would
 >> >> > > produce 0% duty cycle instead of whatever was requested. Rounding rate
 >> >> > > will introduce significant complexity into the driver. Most of the time
 >> >> > > if a consumer requests an invalid rate, it is due to misconfiguration
 >> >> > > which is best solved by fixing the configuration.
 >> >> >
 >> >> > In the first step pick the biggest period not bigger than the requested
 >> >> > and then pick the biggest duty cycle that is not bigger than the
 >> >> > requested and that can be set with the just picked period. That is the
 >> >> > behaviour that all new drivers should do. This is somewhat arbitrary but
 >> >> > after quite some thought the most sensible in my eyes.
 >> >>
 >> >> And if there are no periods smaller than the requested period?
 >> >
 >> > Then return -ERANGE.
 >>
 >> Ok, so instead of
 >>
 >> 	if (cycles < 2 || cycles > priv->max + 2)
 >> 		return -ERANGE;
 >>
 >> you would prefer
 >>
 >> 	if (cycles < 2)
 >> 		return -ERANGE;
 >> 	else if (cycles > priv->max + 2)
 >> 		cycles = priv->max;
 >
 > The actual calculation is a bit harder to handle TCSR_UDT = 0 but in
 > principle, yes, but see below.
 >
 >> But if we do the above clamping for TLR0, then we have to recalculate
 >> the duty cycle for TLR1. Which I guess means doing something like
 >>
 >> 	ret = xilinx_timer_tlr_period(priv, &tlr0, tcsr0, state->period);
 >> 	if (ret)
 >> 		return ret;
 >>
 >> 	state->duty_cycle = mult_frac(state->duty_cycle,
 >> 				      xilinx_timer_get_period(priv, tlr0, tcsr0),
 >> 				      state->period);
 >>
 >> 	ret = xilinx_timer_tlr_period(priv, &tlr1, tcsr1, state->duty_cycle);
 >> 	if (ret)
 >> 		return ret;
 >
 > No, you need something like:
 >
 > 	/*
 > 	 * The multiplication cannot overflow as both priv_max and
 > 	 * NSEC_PER_SEC fit into an u32.
 > 	 */
 > 	max_period = div64_ul((u64)priv->max * NSEC_PER_SEC, clkrate);
 >
 > 	/* cap period to the maximal possible value */
 > 	if (state->period > max_period)
 > 		period = max_period;
 > 	else
 > 		period = state->period;
 >
 > 	/* cap duty_cycle to the maximal possible value */
 > 	if (state->duty_cycle > max_period)
 > 		duty_cycle = max_period;
 > 	else
 > 		duty_cycle = state->duty_cycle;

These caps may increase the % duty cycle. For example, consider when the
max is 100, and the user requests a period of 150 and a duty cycle of
75, for a % duty cycle of 50%. The current logic is equivalent to

	period = min(state->period, max_period);
	duty_cycle = min(state->duty_cycle, max_period);

Which will result in a period of 100 and a duty cycle of 75, for a 75%
duty cycle. Instead, we should do

	period = min(state->period, max_period);
	duty_cycle = mult_frac(state->duty_cycle, period, state->period);

which will result in a period of 100 and a duty cycle of 50.

 > 	period_cycles = period * clkrate / NSEC_PER_SEC;
 >
 > 	if (period_cycles < 2)
 > 		return -ERANGE;
 >
 > 	duty_cycles = duty_cycle * clkrate / NSEC_PER_SEC;
 >
 > 	/*
 > 	 * The hardware cannot emit a 100% relative duty cycle, if
 > 	 * duty_cycle >= period_cycles is programmed the hardware emits
 > 	 * a 0% relative duty cycle.
 > 	 */
 > 	if (duty_cycle == period_cycles)
 > 		duty_cycles = period_cycles - 1;
 >
 > 	/*
 > 	 * The hardware cannot emit a duty_cycle of one clk step, so
 > 	 * emit 0 instead.
 > 	 */
 > 	if (duty_cycles < 2)
 > 		duty_cycles = period_cycles;

Of course, the above may result in 100% duty cycle being rounded down to
0%. I feel like that is too big of a jump to ignore. Perhaps if we
cannot return -ERANGE we should at least dev_warn.

--Sean

 >> >> > > > > Perhaps I should add
 >> >> > > > >
 >> >> > > > > 	if (tlr0 <= tlr1)
 >> >> > > > > 		return -EINVAL;
 >> >> > > > >
 >> >> > > > > here to prevent accidentally getting 0% duty cycle.
 >> >> > > >
 >> >> > > > You can assume that duty_cycle <= period when .apply is called.
 >> >> > >
 >> >> > > Ok, I will only check for == then.
 >> >> >
 >> >> > You just have to pay attention to the case that you had to decrement
 >> >> > .period to the next possible value. Then .duty_cycle might be bigger
 >> >> > than the corrected period.
 >> >>
 >> >> This is specifically to prevent 100% duty cycle from turning into 0%. My
 >> >> current draft is
 >> >>
 >> >> 	/*
 >> >> 	 * If TLR0 == TLR1, then we will produce 0% duty cycle instead of 100%
 >> >> 	 * duty cycle. Try and reduce the high time to compensate. If we can't
 >> >> 	 * do that because the high time is already 0 cycles, then just error
 >> >> 	 * out.
 >> >> 	 */
 >> >> 	if (tlr0 == tlr1 && !tlr1--)
 >> >> 		return -EINVAL;
 >> >
 >> > If you follow my suggested policy this isn't an error and you should
 >> > yield the biggest duty_cycle here even if it is zero.
 >>
 >> So like this?
 >>
 >> 	if (tlr0 == tlr1) {
 >> 		if (tlr1)
 >> 			tlr1--;
 >> 		else if (tlr0 != priv->max)
 >> 			tlr0++;
 >> 		else
 >> 			return -ERANGE;
 >> 	}
 >
 > No, this is wrong as it configures a longer period than requested in
 > some cases.
 >
 >> And I would really appreciate if you could write up some documentation
 >> with common errors and how to handle them. It's not at all obvious to me
 >> what all the implications of the above guidelines are.
 >
 > Yes, I fully agree this should be documented and doing that is on my
 > todo list. Until I come around to do this, enabling PWM_DEBUG should
 > help you getting this right (assuming you test extensively and read the
 > resulting kernel messages).
 >
 > Best regards
 > Uwe
 >

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2021-06-29 18:01 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-28 21:45 [PATCH v4 1/3] dt-bindings: pwm: Add Xilinx AXI Timer Sean Anderson
2021-05-28 21:45 ` Sean Anderson
2021-05-28 21:45 ` [PATCH v4 2/3] clocksource: Rewrite Xilinx AXI timer driver Sean Anderson
2021-05-28 21:45   ` Sean Anderson
2021-06-01  8:47   ` Lee Jones
2021-06-01  8:47     ` Lee Jones
2021-06-01 14:24     ` Sean Anderson
2021-06-01 14:24       ` Sean Anderson
2021-05-28 21:45 ` [PATCH v4 3/3] pwm: Add support for Xilinx AXI Timer Sean Anderson
2021-05-28 21:45   ` Sean Anderson
2021-06-10 16:15   ` Sean Anderson
2021-06-10 16:15     ` Sean Anderson
2021-06-25  6:19   ` Uwe Kleine-König
2021-06-25  6:19     ` Uwe Kleine-König
2021-06-25 15:13     ` Sean Anderson
2021-06-25 15:13       ` Sean Anderson
2021-06-25 16:56       ` Uwe Kleine-König
2021-06-25 16:56         ` Uwe Kleine-König
2021-06-25 17:46         ` Sean Anderson
2021-06-25 17:46           ` Sean Anderson
2021-06-25 17:46         ` Sean Anderson
2021-06-25 17:46           ` Sean Anderson
2021-06-27 18:19           ` Uwe Kleine-König
2021-06-27 18:19             ` Uwe Kleine-König
2021-06-28 15:50             ` Sean Anderson
2021-06-28 15:50               ` Sean Anderson
2021-06-28 16:24               ` Uwe Kleine-König
2021-06-28 16:24                 ` Uwe Kleine-König
2021-06-28 16:35                 ` Sean Anderson
2021-06-28 16:35                   ` Sean Anderson
2021-06-28 17:20                   ` Uwe Kleine-König
2021-06-28 17:20                     ` Uwe Kleine-König
2021-06-28 17:41                     ` Sean Anderson
2021-06-28 17:41                       ` Sean Anderson
2021-06-29  8:31                       ` Uwe Kleine-König
2021-06-29  8:31                         ` Uwe Kleine-König
2021-06-29 18:01                         ` Sean Anderson [this message]
2021-06-29 18:01                           ` Sean Anderson
2021-06-29 20:51                           ` Uwe Kleine-König
2021-06-29 20:51                             ` Uwe Kleine-König
2021-06-29 22:21                             ` Sean Anderson
2021-06-29 22:21                               ` Sean Anderson
2021-06-29 22:26                               ` Sean Anderson
2021-06-29 22:26                                 ` Sean Anderson
2021-06-30  8:35                               ` Uwe Kleine-König
2021-06-30  8:35                                 ` Uwe Kleine-König
2021-07-08 16:59                                 ` Sean Anderson
2021-07-08 16:59                                   ` Sean Anderson
2021-07-08 19:43                                   ` Uwe Kleine-König
2021-07-08 19:43                                     ` Uwe Kleine-König
2021-07-12 16:26                                     ` Sean Anderson
2021-07-12 16:26                                       ` Sean Anderson
2021-07-12 19:49                                       ` Uwe Kleine-König
2021-07-12 19:49                                         ` Uwe Kleine-König
2021-07-13 21:49                                         ` Sean Anderson
2021-07-13 21:49                                           ` Sean Anderson
2021-06-01 13:32 ` [PATCH v4 1/3] dt-bindings: pwm: Add " Rob Herring
2021-06-01 13:32   ` Rob Herring
2021-06-01 16:47   ` Sean Anderson
2021-06-01 16:47     ` Sean Anderson
2021-06-29  8:38 ` Uwe Kleine-König
2021-06-29  8:38   ` Uwe Kleine-König
2021-06-29 14:53   ` Sean Anderson
2021-06-29 14:53     ` Sean Anderson
2021-06-30 13:47 ` Michal Simek
2021-06-30 13:47   ` Michal Simek
2021-06-30 13:58   ` Michal Simek
2021-06-30 13:58     ` Michal Simek
2021-07-01 15:38     ` Sean Anderson
2021-07-01 15:38       ` Sean Anderson
2021-07-02 11:36       ` Michal Simek
2021-07-02 11:36         ` Michal Simek
2021-07-01 15:32   ` Sean Anderson
2021-07-01 15:32     ` Sean Anderson
2021-07-02 12:40     ` Michal Simek
2021-07-02 12:40       ` Michal Simek
2021-07-02 17:31       ` Sean Anderson
2021-07-02 17:31         ` Sean Anderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a4943aa5-956c-1820-3489-994f0812c3a7@seco.com \
    --to=sean.anderson@seco.com \
    --cc=alvaro.gamez@hazent.com \
    --cc=devicetree@vger.kernel.org \
    --cc=emil.lenngren@gmail.com \
    --cc=kernel@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pwm@vger.kernel.org \
    --cc=michal.simek@xilinx.com \
    --cc=thierry.reding@gmail.com \
    --cc=u.kleine-koenig@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.