Revert "media: cec: call enable_adap on s_log_addrs"

This reverts commit 2c67f3634f which is
commit 3813c932ed970dd4f413498ccecb03c73c4f1784 upstream.

It breaks the Android kernel abi and can be brought back in the future
in an abi-safe way if it is really needed.

Bug: 161946584
Change-Id: I042a2e45c1b5e48db8fe5aab647d18c0a2d28632
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2024-07-15 17:19:57 +00:00
parent f257da513d
commit 12d97237e4
3 changed files with 64 additions and 130 deletions

View File

@@ -1532,7 +1532,6 @@ static void cec_claim_log_addrs(struct cec_adapter *adap, bool block)
"ceccfg-%s", adap->name); "ceccfg-%s", adap->name);
if (IS_ERR(adap->kthread_config)) { if (IS_ERR(adap->kthread_config)) {
adap->kthread_config = NULL; adap->kthread_config = NULL;
adap->is_configuring = false;
} else if (block) { } else if (block) {
mutex_unlock(&adap->lock); mutex_unlock(&adap->lock);
wait_for_completion(&adap->config_completion); wait_for_completion(&adap->config_completion);
@@ -1540,91 +1539,60 @@ static void cec_claim_log_addrs(struct cec_adapter *adap, bool block)
} }
} }
/*
* Helper functions to enable/disable the CEC adapter.
*
* These functions are called with adap->lock held.
*/
static int cec_activate_cnt_inc(struct cec_adapter *adap)
{
int ret;
if (adap->activate_cnt++)
return 0;
/* serialize adap_enable */
mutex_lock(&adap->devnode.lock);
adap->last_initiator = 0xff;
adap->transmit_in_progress = false;
ret = adap->ops->adap_enable(adap, true);
if (ret)
adap->activate_cnt--;
mutex_unlock(&adap->devnode.lock);
return ret;
}
static void cec_activate_cnt_dec(struct cec_adapter *adap)
{
if (WARN_ON(!adap->activate_cnt))
return;
if (--adap->activate_cnt)
return;
/* serialize adap_enable */
mutex_lock(&adap->devnode.lock);
WARN_ON(adap->ops->adap_enable(adap, false));
adap->last_initiator = 0xff;
adap->transmit_in_progress = false;
mutex_unlock(&adap->devnode.lock);
}
/* Set a new physical address and send an event notifying userspace of this. /* Set a new physical address and send an event notifying userspace of this.
* *
* This function is called with adap->lock held. * This function is called with adap->lock held.
*/ */
void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
{ {
bool becomes_invalid = phys_addr == CEC_PHYS_ADDR_INVALID;
bool is_invalid = adap->phys_addr == CEC_PHYS_ADDR_INVALID;
if (phys_addr == adap->phys_addr) if (phys_addr == adap->phys_addr)
return; return;
if (!becomes_invalid && adap->devnode.unregistered) if (phys_addr != CEC_PHYS_ADDR_INVALID && adap->devnode.unregistered)
return; return;
dprintk(1, "new physical address %x.%x.%x.%x\n", dprintk(1, "new physical address %x.%x.%x.%x\n",
cec_phys_addr_exp(phys_addr)); cec_phys_addr_exp(phys_addr));
if (becomes_invalid || !is_invalid) { if (phys_addr == CEC_PHYS_ADDR_INVALID ||
adap->phys_addr != CEC_PHYS_ADDR_INVALID) {
adap->phys_addr = CEC_PHYS_ADDR_INVALID; adap->phys_addr = CEC_PHYS_ADDR_INVALID;
cec_post_state_event(adap); cec_post_state_event(adap);
cec_adap_unconfigure(adap); cec_adap_unconfigure(adap);
if (becomes_invalid && adap->needs_hpd) { /* Disabling monitor all mode should always succeed */
/* Disable monitor-all/pin modes if needed */ if (adap->monitor_all_cnt)
if (adap->monitor_all_cnt) WARN_ON(call_op(adap, adap_monitor_all_enable, false));
WARN_ON(call_op(adap, adap_monitor_all_enable, false)); /* serialize adap_enable */
if (adap->monitor_pin_cnt) mutex_lock(&adap->devnode.lock);
WARN_ON(call_op(adap, adap_monitor_pin_enable, false)); if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) {
cec_activate_cnt_dec(adap); WARN_ON(adap->ops->adap_enable(adap, false));
adap->transmit_in_progress = false;
wake_up_interruptible(&adap->kthread_waitq); wake_up_interruptible(&adap->kthread_waitq);
} }
if (becomes_invalid) mutex_unlock(&adap->devnode.lock);
if (phys_addr == CEC_PHYS_ADDR_INVALID)
return; return;
} }
if (is_invalid && adap->needs_hpd) { /* serialize adap_enable */
if (cec_activate_cnt_inc(adap)) mutex_lock(&adap->devnode.lock);
adap->last_initiator = 0xff;
adap->transmit_in_progress = false;
if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) {
if (adap->ops->adap_enable(adap, true)) {
mutex_unlock(&adap->devnode.lock);
return; return;
/* }
* Re-enable monitor-all/pin modes if needed. We warn, but
* continue if this fails as this is not a critical error.
*/
if (adap->monitor_all_cnt)
WARN_ON(call_op(adap, adap_monitor_all_enable, true));
if (adap->monitor_pin_cnt)
WARN_ON(call_op(adap, adap_monitor_pin_enable, true));
} }
if (adap->monitor_all_cnt &&
call_op(adap, adap_monitor_all_enable, true)) {
if (adap->needs_hpd || list_empty(&adap->devnode.fhs))
WARN_ON(adap->ops->adap_enable(adap, false));
mutex_unlock(&adap->devnode.lock);
return;
}
mutex_unlock(&adap->devnode.lock);
adap->phys_addr = phys_addr; adap->phys_addr = phys_addr;
cec_post_state_event(adap); cec_post_state_event(adap);
if (adap->log_addrs.num_log_addrs) if (adap->log_addrs.num_log_addrs)
@@ -1688,8 +1656,6 @@ int __cec_s_log_addrs(struct cec_adapter *adap,
return -ENODEV; return -ENODEV;
if (!log_addrs || log_addrs->num_log_addrs == 0) { if (!log_addrs || log_addrs->num_log_addrs == 0) {
if (!adap->is_configuring && !adap->is_configured)
return 0;
cec_adap_unconfigure(adap); cec_adap_unconfigure(adap);
adap->log_addrs.num_log_addrs = 0; adap->log_addrs.num_log_addrs = 0;
for (i = 0; i < CEC_MAX_LOG_ADDRS; i++) for (i = 0; i < CEC_MAX_LOG_ADDRS; i++)
@@ -1697,8 +1663,6 @@ int __cec_s_log_addrs(struct cec_adapter *adap,
adap->log_addrs.osd_name[0] = '\0'; adap->log_addrs.osd_name[0] = '\0';
adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE; adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE;
adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
if (!adap->needs_hpd)
cec_activate_cnt_dec(adap);
return 0; return 0;
} }
@@ -1832,12 +1796,6 @@ int __cec_s_log_addrs(struct cec_adapter *adap,
sizeof(log_addrs->features[i])); sizeof(log_addrs->features[i]));
} }
if (!adap->needs_hpd && !adap->is_configuring && !adap->is_configured) {
int ret = cec_activate_cnt_inc(adap);
if (ret)
return ret;
}
log_addrs->log_addr_mask = adap->log_addrs.log_addr_mask; log_addrs->log_addr_mask = adap->log_addrs.log_addr_mask;
adap->log_addrs = *log_addrs; adap->log_addrs = *log_addrs;
if (adap->phys_addr != CEC_PHYS_ADDR_INVALID) if (adap->phys_addr != CEC_PHYS_ADDR_INVALID)
@@ -2141,37 +2099,20 @@ skip_processing:
*/ */
int cec_monitor_all_cnt_inc(struct cec_adapter *adap) int cec_monitor_all_cnt_inc(struct cec_adapter *adap)
{ {
int ret; int ret = 0;
if (adap->monitor_all_cnt++) if (adap->monitor_all_cnt == 0)
return 0; ret = call_op(adap, adap_monitor_all_enable, 1);
if (ret == 0)
if (!adap->needs_hpd) { adap->monitor_all_cnt++;
ret = cec_activate_cnt_inc(adap);
if (ret) {
adap->monitor_all_cnt--;
return ret;
}
}
ret = call_op(adap, adap_monitor_all_enable, true);
if (ret) {
adap->monitor_all_cnt--;
if (!adap->needs_hpd)
cec_activate_cnt_dec(adap);
}
return ret; return ret;
} }
void cec_monitor_all_cnt_dec(struct cec_adapter *adap) void cec_monitor_all_cnt_dec(struct cec_adapter *adap)
{ {
if (WARN_ON(!adap->monitor_all_cnt)) adap->monitor_all_cnt--;
return; if (adap->monitor_all_cnt == 0)
if (--adap->monitor_all_cnt) WARN_ON(call_op(adap, adap_monitor_all_enable, 0));
return;
WARN_ON(call_op(adap, adap_monitor_all_enable, false));
if (!adap->needs_hpd)
cec_activate_cnt_dec(adap);
} }
/* /*
@@ -2181,37 +2122,20 @@ void cec_monitor_all_cnt_dec(struct cec_adapter *adap)
*/ */
int cec_monitor_pin_cnt_inc(struct cec_adapter *adap) int cec_monitor_pin_cnt_inc(struct cec_adapter *adap)
{ {
int ret; int ret = 0;
if (adap->monitor_pin_cnt++) if (adap->monitor_pin_cnt == 0)
return 0; ret = call_op(adap, adap_monitor_pin_enable, 1);
if (ret == 0)
if (!adap->needs_hpd) { adap->monitor_pin_cnt++;
ret = cec_activate_cnt_inc(adap);
if (ret) {
adap->monitor_pin_cnt--;
return ret;
}
}
ret = call_op(adap, adap_monitor_pin_enable, true);
if (ret) {
adap->monitor_pin_cnt--;
if (!adap->needs_hpd)
cec_activate_cnt_dec(adap);
}
return ret; return ret;
} }
void cec_monitor_pin_cnt_dec(struct cec_adapter *adap) void cec_monitor_pin_cnt_dec(struct cec_adapter *adap)
{ {
if (WARN_ON(!adap->monitor_pin_cnt)) adap->monitor_pin_cnt--;
return; if (adap->monitor_pin_cnt == 0)
if (--adap->monitor_pin_cnt) WARN_ON(call_op(adap, adap_monitor_pin_enable, 0));
return;
WARN_ON(call_op(adap, adap_monitor_pin_enable, false));
if (!adap->needs_hpd)
cec_activate_cnt_dec(adap);
} }
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
@@ -2225,7 +2149,6 @@ int cec_adap_status(struct seq_file *file, void *priv)
struct cec_data *data; struct cec_data *data;
mutex_lock(&adap->lock); mutex_lock(&adap->lock);
seq_printf(file, "activation count: %u\n", adap->activate_cnt);
seq_printf(file, "configured: %d\n", adap->is_configured); seq_printf(file, "configured: %d\n", adap->is_configured);
seq_printf(file, "configuring: %d\n", adap->is_configuring); seq_printf(file, "configuring: %d\n", adap->is_configuring);
seq_printf(file, "phys_addr: %x.%x.%x.%x\n", seq_printf(file, "phys_addr: %x.%x.%x.%x\n",
@@ -2240,9 +2163,6 @@ int cec_adap_status(struct seq_file *file, void *priv)
if (adap->monitor_all_cnt) if (adap->monitor_all_cnt)
seq_printf(file, "file handles in Monitor All mode: %u\n", seq_printf(file, "file handles in Monitor All mode: %u\n",
adap->monitor_all_cnt); adap->monitor_all_cnt);
if (adap->monitor_pin_cnt)
seq_printf(file, "file handles in Monitor Pin mode: %u\n",
adap->monitor_pin_cnt);
if (adap->tx_timeouts) { if (adap->tx_timeouts) {
seq_printf(file, "transmit timeouts: %u\n", seq_printf(file, "transmit timeouts: %u\n",
adap->tx_timeouts); adap->tx_timeouts);

View File

@@ -586,6 +586,18 @@ static int cec_open(struct inode *inode, struct file *filp)
return err; return err;
} }
/* serialize adap_enable */
mutex_lock(&devnode->lock);
if (list_empty(&devnode->fhs) &&
!adap->needs_hpd &&
adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
err = adap->ops->adap_enable(adap, true);
if (err) {
mutex_unlock(&devnode->lock);
kfree(fh);
return err;
}
}
filp->private_data = fh; filp->private_data = fh;
/* Queue up initial state events */ /* Queue up initial state events */
@@ -613,7 +625,6 @@ static int cec_open(struct inode *inode, struct file *filp)
} }
#endif #endif
mutex_lock(&devnode->lock);
mutex_lock(&devnode->lock_fhs); mutex_lock(&devnode->lock_fhs);
list_add(&fh->list, &devnode->fhs); list_add(&fh->list, &devnode->fhs);
mutex_unlock(&devnode->lock_fhs); mutex_unlock(&devnode->lock_fhs);
@@ -645,10 +656,15 @@ static int cec_release(struct inode *inode, struct file *filp)
cec_monitor_all_cnt_dec(adap); cec_monitor_all_cnt_dec(adap);
mutex_unlock(&adap->lock); mutex_unlock(&adap->lock);
/* serialize adap_enable */
mutex_lock(&devnode->lock); mutex_lock(&devnode->lock);
mutex_lock(&devnode->lock_fhs); mutex_lock(&devnode->lock_fhs);
list_del(&fh->list); list_del(&fh->list);
mutex_unlock(&devnode->lock_fhs); mutex_unlock(&devnode->lock_fhs);
if (cec_is_registered(adap) && list_empty(&devnode->fhs) &&
!adap->needs_hpd && adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
WARN_ON(adap->ops->adap_enable(adap, false));
}
mutex_unlock(&devnode->lock); mutex_unlock(&devnode->lock);
/* Unhook pending transmits from this filehandle. */ /* Unhook pending transmits from this filehandle. */

View File

@@ -185,7 +185,6 @@ struct cec_adap_ops {
* Drivers that need this can set this field to true after the * Drivers that need this can set this field to true after the
* cec_allocate_adapter() call. * cec_allocate_adapter() call.
* @last_initiator: the initiator of the last transmitted message. * @last_initiator: the initiator of the last transmitted message.
* @activate_cnt: number of times that CEC is activated
* @monitor_all_cnt: number of filehandles monitoring all msgs * @monitor_all_cnt: number of filehandles monitoring all msgs
* @monitor_pin_cnt: number of filehandles monitoring pin changes * @monitor_pin_cnt: number of filehandles monitoring pin changes
* @follower_cnt: number of filehandles in follower mode * @follower_cnt: number of filehandles in follower mode
@@ -237,7 +236,6 @@ struct cec_adapter {
bool cec_pin_is_high; bool cec_pin_is_high;
bool adap_controls_phys_addr; bool adap_controls_phys_addr;
u8 last_initiator; u8 last_initiator;
u32 activate_cnt;
u32 monitor_all_cnt; u32 monitor_all_cnt;
u32 monitor_pin_cnt; u32 monitor_pin_cnt;
u32 follower_cnt; u32 follower_cnt;