diff options
| author | Hans Verkuil <hverkuil@xs4all.nl> | 2025-06-30 14:08:50 +0300 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2025-07-08 09:35:27 +0300 |
| commit | 5701c792c7b9348adca640f24bb01d69ba657e03 (patch) | |
| tree | 53fefd11877ad5a10576ee03e7ca03b650fbc4fe | |
| parent | e068fbdf4ccb503dd05126361b6e587abc0e7d9f (diff) | |
| download | linux-5701c792c7b9348adca640f24bb01d69ba657e03.tar.xz | |
media: cec: cec-gpio: reading hpd/5v is allowed to sleep
Reading the hpd or 5v gpios is something that can sleep, so rework
the code to allow this.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
| -rw-r--r-- | drivers/media/cec/platform/cec-gpio/cec-gpio.c | 26 |
1 files 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 = { |
