Files
LibreELEC.tv/packages/linux/patches/rockchip-old/rockchip-0026-WIP-1000-media-cec-adap-add-debounce-support-when-se.patch
Christian Hewitt 334b6a6e6b linux: add Rockchip kernel and patches for Linux 6.16.y and 6.17.y
Patches for RK356X, RK3576 and RK3588 are placed in a 'rockchip'
folder under the Linux package dir. Boards use a common aarch64
arch defconfig.

Patches for RK3288, RK3328 and RK3399 are moved to a 'rockchip-old'
folder under the Linux package dir. Boards continue to use device
level 6.16.y defconfigs to ensure all drivers are present, except
for RK3288 which has been moved to the project level folder to be
the common arm arch defconfig.

Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
2025-09-12 09:31:57 +00:00

158 lines
6.0 KiB
Diff

From 47cfcb55dc96df812538b733a56a8ca5b9340cac Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Tue, 1 Oct 2019 20:52:42 +0000
Subject: [PATCH 26/59] WIP/1000: media: cec-adap: add debounce support when
setting an invalid phys addr
When EDID is refreshed, HDMI cable is unplugged/replugged or
an AVR is power cycled the CEC phys addr gets invalidated.
This can cause some disruption of CEC communication when
adapter is being reconfigured.
Add a debounce_ms module option that can be used to debounce setting
an invalid phys addr. Default is not to use debouncing.
Using a configured debounce_ms of e.g. 5000 ms, cec reconfiguring
could be avoided when AVR was power cycled on my setup.
Power off AVR (default cec.debounce_ms=0):
[ 101.536866] cec-dw_hdmi: new physical address f.f.f.f
[ 102.495686] cec-dw_hdmi: new physical address 2.1.0.0
[ 102.495913] cec-dw_hdmi: physical address: 2.1.0.0, claim 1 logical addresses
[ 102.628574] cec-dw_hdmi: config: la 1 pa 2.1.0.0
[ 105.130115] cec-dw_hdmi: new physical address f.f.f.f
[ 106.979705] cec-dw_hdmi: new physical address 2.1.0.0
[ 106.979872] cec-dw_hdmi: physical address: 2.1.0.0, claim 1 logical addresses
[ 107.112399] cec-dw_hdmi: config: la 1 pa 2.1.0.0
[ 108.979408] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 5
[ 109.205386] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 11
Power on AVR (default cec.debounce_ms=0):
[ 158.398447] cec-dw_hdmi: new physical address f.f.f.f
[ 161.977714] cec-dw_hdmi: new physical address 2.1.0.0
[ 161.978766] cec-dw_hdmi: physical address: 2.1.0.0, claim 1 logical addresses
[ 162.115624] cec-dw_hdmi: config: la 1 pa 2.1.0.0
[ 162.402750] cec-dw_hdmi: new physical address f.f.f.f
[ 162.403389] cec-dw_hdmi: cec_transmit_msg_fh: adapter is unconfigured
[ 162.886757] cec-dw_hdmi: new physical address 2.1.0.0
[ 162.886964] cec-dw_hdmi: physical address: 2.1.0.0, claim 1 logical addresses
[ 163.510725] cec-dw_hdmi: config: la 1 pa 2.1.0.0
[ 173.034200] cec-dw_hdmi: message 10 89 02 05 timed out
Power off AVR (cec.debounce_ms=5000):
[ 251.720471] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 5
[ 251.922432] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 11
Power on AVR (cec.debounce_ms=5000):
[ 291.154262] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 5
[ 291.296199] cec-dw_hdmi: reported physical address 2.0.0.0 for logical address 11
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/media/cec/core/cec-adap.c | 9 ++++++++-
drivers/media/cec/core/cec-core.c | 18 ++++++++++++++++++
drivers/media/cec/core/cec-priv.h | 1 +
include/media/cec.h | 2 ++
4 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
index ba6828ef540e..ee6f0f706f95 100644
--- a/drivers/media/cec/core/cec-adap.c
+++ b/drivers/media/cec/core/cec-adap.c
@@ -1734,8 +1734,15 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
if (IS_ERR_OR_NULL(adap))
return;
+ cancel_delayed_work_sync(&adap->debounce_work);
+
mutex_lock(&adap->lock);
- __cec_s_phys_addr(adap, phys_addr, block);
+ if (cec_debounce_ms > 0 && !block && phys_addr == CEC_PHYS_ADDR_INVALID &&
+ adap->phys_addr != phys_addr)
+ schedule_delayed_work(&adap->debounce_work,
+ msecs_to_jiffies(cec_debounce_ms));
+ else
+ __cec_s_phys_addr(adap, phys_addr, block);
mutex_unlock(&adap->lock);
}
EXPORT_SYMBOL_GPL(cec_s_phys_addr);
diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c
index e10bd588a586..effb4dd70b97 100644
--- a/drivers/media/cec/core/cec-core.c
+++ b/drivers/media/cec/core/cec-core.c
@@ -41,6 +41,10 @@ static bool debug_phys_addr;
module_param(debug_phys_addr, bool, 0644);
MODULE_PARM_DESC(debug_phys_addr, "add CEC_CAP_PHYS_ADDR if set");
+int cec_debounce_ms;
+module_param_named(debounce_ms, cec_debounce_ms, int, 0644);
+MODULE_PARM_DESC(debounce_ms, "debounce invalid phys addr");
+
static dev_t cec_dev_t;
/* Active devices */
@@ -160,6 +164,8 @@ static void cec_devnode_unregister(struct cec_adapter *adap)
mutex_unlock(&devnode->lock);
+ cancel_delayed_work_sync(&adap->debounce_work);
+
mutex_lock(&adap->lock);
__cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
__cec_s_log_addrs(adap, NULL, false);
@@ -220,6 +226,17 @@ static const struct file_operations cec_error_inj_fops = {
};
#endif
+static void cec_s_phys_addr_debounce(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct cec_adapter *adap =
+ container_of(delayed_work, struct cec_adapter, debounce_work);
+
+ mutex_lock(&adap->lock);
+ __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
+ mutex_unlock(&adap->lock);
+}
+
struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
void *priv, const char *name, u32 caps,
u8 available_las)
@@ -257,6 +274,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
INIT_LIST_HEAD(&adap->transmit_queue);
INIT_LIST_HEAD(&adap->wait_queue);
init_waitqueue_head(&adap->kthread_waitq);
+ INIT_DELAYED_WORK(&adap->debounce_work, cec_s_phys_addr_debounce);
/* adap->devnode initialization */
INIT_LIST_HEAD(&adap->devnode.fhs);
diff --git a/drivers/media/cec/core/cec-priv.h b/drivers/media/cec/core/cec-priv.h
index ce42a37c4ac0..24856163e295 100644
--- a/drivers/media/cec/core/cec-priv.h
+++ b/drivers/media/cec/core/cec-priv.h
@@ -37,6 +37,7 @@ static inline bool msg_is_raw(const struct cec_msg *msg)
/* cec-core.c */
extern int cec_debug;
+extern int cec_debounce_ms;
/* cec-adap.c */
int cec_monitor_all_cnt_inc(struct cec_adapter *adap);
diff --git a/include/media/cec.h b/include/media/cec.h
index 0c8e86115b6f..b35212bebf9c 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -252,6 +252,8 @@ struct cec_adapter {
struct task_struct *kthread;
wait_queue_head_t kthread_waitq;
+ struct delayed_work debounce_work;
+
const struct cec_adap_ops *ops;
void *priv;
u32 capabilities;
--
2.34.1