* [PATCH] media: gpio-ir-tx: re-introduce sleeping for periods of > 50us
@ 2020-09-22 12:17 Sean Young
0 siblings, 0 replies; only message in thread
From: Sean Young @ 2020-09-22 12:17 UTC (permalink / raw)
To: linux-media; +Cc: Pavel Machek
After commit ea8912b788f8 ("media: gpio-ir-tx: improve precision of
transmitted signal due to scheduling"), the gpio-ir-tx driver disables
interrupts for the entire duration of an IR frame, which is 500ms.
Experimentation on an raspberry pi 3 model b under various loads shows that
sleeping can be done using usleep_range() for periods > 40us.
Fixes: ea8912b788f8 ("media: gpio-ir-tx: improve precision of transmitted signal due to scheduling")
Link: https://lkml.org/lkml/2020/9/2/304
Suggested-by: Pavel Machek <pavel@denx.de>
Signed-off-by: Sean Young <sean@mess.org>
---
drivers/media/rc/gpio-ir-tx.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/media/rc/gpio-ir-tx.c b/drivers/media/rc/gpio-ir-tx.c
index c6cd2e6d8e65..be77c5b0d9d0 100644
--- a/drivers/media/rc/gpio-ir-tx.c
+++ b/drivers/media/rc/gpio-ir-tx.c
@@ -51,11 +51,12 @@ static int gpio_ir_tx_set_carrier(struct rc_dev *dev, u32 carrier)
static void gpio_ir_tx_unmodulated(struct gpio_ir *gpio_ir, uint *txbuf,
uint count)
{
+ unsigned long flags;
ktime_t edge;
s32 delta;
int i;
- local_irq_disable();
+ local_irq_save(flags);
edge = ktime_get();
@@ -64,16 +65,25 @@ static void gpio_ir_tx_unmodulated(struct gpio_ir *gpio_ir, uint *txbuf,
edge = ktime_add_us(edge, txbuf[i]);
delta = ktime_us_delta(edge, ktime_get());
+ if (delta > 50) {
+ local_irq_restore(flags);
+ usleep_range(delta - 40, delta - 40);
+ local_irq_save(flags);
+ delta = ktime_us_delta(edge, ktime_get());
+ }
if (delta > 0)
udelay(delta);
}
gpiod_set_value(gpio_ir->gpio, 0);
+
+ local_irq_restore(flags);
}
static void gpio_ir_tx_modulated(struct gpio_ir *gpio_ir, uint *txbuf,
uint count)
{
+ unsigned long flags;
ktime_t edge;
/*
* delta should never exceed 0.5 seconds (IR_MAX_DURATION) and on
@@ -89,7 +99,7 @@ static void gpio_ir_tx_modulated(struct gpio_ir *gpio_ir, uint *txbuf,
space = DIV_ROUND_CLOSEST((100 - gpio_ir->duty_cycle) *
(NSEC_PER_SEC / 100), gpio_ir->carrier);
- local_irq_disable();
+ local_irq_save(flags);
edge = ktime_get();
@@ -98,6 +108,12 @@ static void gpio_ir_tx_modulated(struct gpio_ir *gpio_ir, uint *txbuf,
// space
edge = ktime_add_us(edge, txbuf[i]);
delta = ktime_us_delta(edge, ktime_get());
+ if (delta > 50) {
+ local_irq_restore(flags);
+ usleep_range(delta - 40, delta - 40);
+ local_irq_save(flags);
+ delta = ktime_us_delta(edge, ktime_get());
+ }
if (delta > 0)
udelay(delta);
} else {
@@ -122,20 +138,19 @@ static void gpio_ir_tx_modulated(struct gpio_ir *gpio_ir, uint *txbuf,
edge = last;
}
}
+
+ local_irq_restore(flags);
}
static int gpio_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
unsigned int count)
{
struct gpio_ir *gpio_ir = dev->priv;
- unsigned long flags;
- local_irq_save(flags);
if (gpio_ir->carrier)
gpio_ir_tx_modulated(gpio_ir, txbuf, count);
else
gpio_ir_tx_unmodulated(gpio_ir, txbuf, count);
- local_irq_restore(flags);
return count;
}
--
2.26.2
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2020-09-22 12:17 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-22 12:17 [PATCH] media: gpio-ir-tx: re-introduce sleeping for periods of > 50us Sean Young
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.