On Mon Jun 30 13:08:50 2025 +0200, Hans Verkuil wrote:
> Reading the hpd or 5v gpios is something that can sleep, so rework
> the code to allow this.
> 
> Signed-off-by: Hans Verkuil <hverk...@xs4all.nl>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+hua...@kernel.org>

Patch committed.

Thanks,
Mauro Carvalho Chehab

 drivers/media/cec/platform/cec-gpio/cec-gpio.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

---

diff --git a/drivers/media/cec/platform/cec-gpio/cec-gpio.c 
b/drivers/media/cec/platform/cec-gpio/cec-gpio.c
index fd5d810d55a6..3c27789d8657 100644
--- a/drivers/media/cec/platform/cec-gpio/cec-gpio.c
+++ b/drivers/media/cec/platform/cec-gpio/cec-gpio.c
@@ -64,7 +64,13 @@ static void cec_gpio_low(struct cec_adapter *adap)
 static irqreturn_t cec_gpio_5v_irq_handler_thread(int irq, void *priv)
 {
        struct cec_gpio *cec = priv;
+       int val = gpiod_get_value_cansleep(cec->v5_gpio);
+       bool is_high = val > 0;
 
+       if (val < 0 || is_high == cec->v5_is_high)
+               return IRQ_HANDLED;
+
+       cec->v5_is_high = is_high;
        cec_queue_pin_5v_event(cec->adap, cec->v5_is_high, cec->v5_ts);
        return IRQ_HANDLED;
 }
@@ -72,20 +78,21 @@ static irqreturn_t cec_gpio_5v_irq_handler_thread(int irq, 
void *priv)
 static irqreturn_t cec_gpio_5v_irq_handler(int irq, void *priv)
 {
        struct cec_gpio *cec = priv;
-       int val = gpiod_get_value(cec->v5_gpio);
-       bool is_high = val > 0;
 
-       if (val < 0 || is_high == cec->v5_is_high)
-               return IRQ_HANDLED;
        cec->v5_ts = ktime_get();
-       cec->v5_is_high = is_high;
        return IRQ_WAKE_THREAD;
 }
 
 static irqreturn_t cec_gpio_hpd_irq_handler_thread(int irq, void *priv)
 {
        struct cec_gpio *cec = priv;
+       int val = gpiod_get_value_cansleep(cec->hpd_gpio);
+       bool is_high = val > 0;
 
+       if (val < 0 || is_high == cec->hpd_is_high)
+               return IRQ_HANDLED;
+
+       cec->hpd_is_high = is_high;
        cec_queue_pin_hpd_event(cec->adap, cec->hpd_is_high, cec->hpd_ts);
        return IRQ_HANDLED;
 }
@@ -93,13 +100,8 @@ static irqreturn_t cec_gpio_hpd_irq_handler_thread(int irq, 
void *priv)
 static irqreturn_t cec_gpio_hpd_irq_handler(int irq, void *priv)
 {
        struct cec_gpio *cec = priv;
-       int val = gpiod_get_value(cec->hpd_gpio);
-       bool is_high = val > 0;
 
-       if (val < 0 || is_high == cec->hpd_is_high)
-               return IRQ_HANDLED;
        cec->hpd_ts = ktime_get();
-       cec->hpd_is_high = is_high;
        return IRQ_WAKE_THREAD;
 }
 
@@ -148,7 +150,7 @@ static int cec_gpio_read_hpd(struct cec_adapter *adap)
 
        if (!cec->hpd_gpio)
                return -ENOTTY;
-       return gpiod_get_value(cec->hpd_gpio);
+       return gpiod_get_value_cansleep(cec->hpd_gpio);
 }
 
 static int cec_gpio_read_5v(struct cec_adapter *adap)
@@ -157,7 +159,7 @@ static int cec_gpio_read_5v(struct cec_adapter *adap)
 
        if (!cec->v5_gpio)
                return -ENOTTY;
-       return gpiod_get_value(cec->v5_gpio);
+       return gpiod_get_value_cansleep(cec->v5_gpio);
 }
 
 static const struct cec_pin_ops cec_gpio_pin_ops = {

Reply via email to