WARN_ON(call_op(adap, adap_monitor_all_enable, 0));
}
+/*
+ * Helper functions to keep track of the 'monitor pin' use count.
+ *
+ * These functions are called with adap->lock held.
+ */
+int cec_monitor_pin_cnt_inc(struct cec_adapter *adap)
+{
+ int ret = 0;
+
+ if (adap->monitor_pin_cnt == 0)
+ ret = call_op(adap, adap_monitor_pin_enable, 1);
+ if (ret == 0)
+ adap->monitor_pin_cnt++;
+ return ret;
+}
+
+void cec_monitor_pin_cnt_dec(struct cec_adapter *adap)
+{
+ adap->monitor_pin_cnt--;
+ if (adap->monitor_pin_cnt == 0)
+ WARN_ON(call_op(adap, adap_monitor_pin_enable, 0));
+}
+
#ifdef CONFIG_DEBUG_FS
/*
* Log the current state of the CEC adapter.
u32 mode;
u8 mode_initiator;
u8 mode_follower;
+ bool send_pin_event = false;
long err = 0;
if (copy_from_user(&mode, parg, sizeof(mode)))
}
}
+ if (!err) {
+ bool old_mon_pin = fh->mode_follower == CEC_MODE_MONITOR_PIN;
+ bool new_mon_pin = mode_follower == CEC_MODE_MONITOR_PIN;
+
+ if (old_mon_pin != new_mon_pin) {
+ send_pin_event = new_mon_pin;
+ if (new_mon_pin)
+ err = cec_monitor_pin_cnt_inc(adap);
+ else
+ cec_monitor_pin_cnt_dec(adap);
+ }
+ }
+
if (err) {
mutex_unlock(&adap->lock);
return err;
if (fh->mode_follower == CEC_MODE_FOLLOWER)
adap->follower_cnt--;
- if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
- adap->monitor_pin_cnt--;
if (mode_follower == CEC_MODE_FOLLOWER)
adap->follower_cnt++;
- if (mode_follower == CEC_MODE_MONITOR_PIN) {
+ if (send_pin_event) {
struct cec_event ev = {
.flags = CEC_EVENT_FL_INITIAL_STATE,
};
ev.event = adap->cec_pin_is_high ? CEC_EVENT_PIN_CEC_HIGH :
CEC_EVENT_PIN_CEC_LOW;
cec_queue_event_fh(fh, &ev, 0);
- adap->monitor_pin_cnt++;
}
if (mode_follower == CEC_MODE_EXCL_FOLLOWER ||
mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) {
if (fh->mode_follower == CEC_MODE_FOLLOWER)
adap->follower_cnt--;
if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
- adap->monitor_pin_cnt--;
+ cec_monitor_pin_cnt_dec(adap);
if (fh->mode_follower == CEC_MODE_MONITOR_ALL)
cec_monitor_all_cnt_dec(adap);
mutex_unlock(&adap->lock);
/* cec-adap.c */
int cec_monitor_all_cnt_inc(struct cec_adapter *adap);
void cec_monitor_all_cnt_dec(struct cec_adapter *adap);
+int cec_monitor_pin_cnt_inc(struct cec_adapter *adap);
+void cec_monitor_pin_cnt_dec(struct cec_adapter *adap);
int cec_adap_status(struct seq_file *file, void *priv);
int cec_thread_func(void *_adap);
void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block);
/* Low-level callbacks */
int (*adap_enable)(struct cec_adapter *adap, bool enable);
int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
+ int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg);