*/
#define CEC_XFER_TIMEOUT_MS (5 * 400 + 100)
-#define call_op(adap, op, arg...) \
- (adap->ops->op ? adap->ops->op(adap, ## arg) : 0)
-
-#define call_void_op(adap, op, arg...) \
- do { \
- if (adap->ops->op) \
- adap->ops->op(adap, ## arg); \
- } while (0)
-
static int cec_log_addr2idx(const struct cec_adapter *adap, u8 log_addr)
{
int i;
/* Queue transmitted message for monitoring purposes */
cec_queue_msg_monitor(adap, &data->msg, 1);
- if (!data->blocking && data->msg.sequence && adap->ops->received)
+ if (!data->blocking && data->msg.sequence)
/* Allow drivers to process the message first */
- adap->ops->received(adap, &data->msg);
+ call_op(adap, received, &data->msg);
cec_data_completed(data);
}
adap->transmit_in_progress_aborted = false;
/* Tell the adapter to transmit, cancel on error */
- if (adap->ops->adap_transmit(adap, data->attempts,
- signal_free_time, &data->msg))
+ if (call_op(adap, adap_transmit, data->attempts,
+ signal_free_time, &data->msg))
cec_data_cancel(data, CEC_TX_STATUS_ABORTED, 0);
else
adap->transmit_in_progress = true;
* Message not acknowledged, so this logical
* address is free to use.
*/
- err = adap->ops->adap_log_addr(adap, log_addr);
+ err = call_op(adap, adap_log_addr, log_addr);
if (err)
return err;
*/
static void cec_adap_unconfigure(struct cec_adapter *adap)
{
- if (!adap->needs_hpd ||
- adap->phys_addr != CEC_PHYS_ADDR_INVALID)
- WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID));
+ if (!adap->needs_hpd || adap->phys_addr != CEC_PHYS_ADDR_INVALID)
+ WARN_ON(call_op(adap, adap_log_addr, CEC_LOG_ADDR_INVALID));
adap->log_addrs.log_addr_mask = 0;
adap->is_configuring = false;
adap->is_configured = false;
mutex_lock(&adap->devnode.lock);
adap->last_initiator = 0xff;
adap->transmit_in_progress = false;
- ret = adap->ops->adap_enable(adap, true);
+ ret = call_op(adap, adap_enable, true);
if (ret)
adap->activate_cnt--;
mutex_unlock(&adap->devnode.lock);
/* serialize adap_enable */
mutex_lock(&adap->devnode.lock);
- WARN_ON(adap->ops->adap_enable(adap, false));
+ WARN_ON(call_op(adap, adap_enable, false));
adap->last_initiator = 0xff;
adap->transmit_in_progress = false;
adap->transmit_in_progress_aborted = false;
msg->msg[1] != CEC_MSG_CDC_MESSAGE)
return 0;
- if (adap->ops->received) {
- /* Allow drivers to process the message first */
- if (adap->ops->received(adap, msg) != -ENOMSG)
- return 0;
- }
+ /* Allow drivers to process the message first */
+ if (adap->ops->received && !adap->devnode.unregistered &&
+ adap->ops->received(adap, msg) != -ENOMSG)
+ return 0;
/*
* REPORT_PHYSICAL_ADDR, CEC_MSG_USER_CONTROL_PRESSED and
adap->conn_info.type != CEC_CONNECTOR_TYPE_NO_CONNECTOR;
cec_queue_event_fh(fh, &ev, 0);
#ifdef CONFIG_CEC_PIN
- if (adap->pin && adap->pin->ops->read_hpd) {
+ if (adap->pin && adap->pin->ops->read_hpd &&
+ !adap->devnode.unregistered) {
err = adap->pin->ops->read_hpd(adap);
if (err >= 0) {
ev.event = err ? CEC_EVENT_PIN_HPD_HIGH :
cec_queue_event_fh(fh, &ev, 0);
}
}
- if (adap->pin && adap->pin->ops->read_5v) {
+ if (adap->pin && adap->pin->ops->read_5v &&
+ !adap->devnode.unregistered) {
err = adap->pin->ops->read_5v(adap);
if (err >= 0) {
ev.event = err ? CEC_EVENT_PIN_5V_HIGH :
line = strsep(&p, "\n");
if (!*line || *line == '#')
continue;
- if (!adap->ops->error_inj_parse_line(adap, line)) {
+ if (!call_op(adap, error_inj_parse_line, line)) {
kfree(buf);
return -EINVAL;
}
{
struct cec_adapter *adap = sf->private;
- return adap->ops->error_inj_show(adap, sf);
+ return call_op(adap, error_inj_show, sf);
}
static int cec_error_inj_open(struct inode *inode, struct file *file)
#include <linux/atomic.h>
#include <media/cec-pin.h>
+#define call_pin_op(pin, op, arg...) \
+ ((pin && pin->ops->op && !pin->adap->devnode.unregistered) ? \
+ pin->ops->op(pin->adap, ## arg) : 0)
+
+#define call_void_pin_op(pin, op, arg...) \
+ do { \
+ if (pin && pin->ops->op && \
+ !pin->adap->devnode.unregistered) \
+ pin->ops->op(pin->adap, ## arg); \
+ } while (0)
+
enum cec_pin_state {
/* CEC is off */
CEC_ST_OFF,
static bool cec_pin_read(struct cec_pin *pin)
{
- bool v = pin->ops->read(pin->adap);
+ bool v = call_pin_op(pin, read);
cec_pin_update(pin, v, false);
return v;
static void cec_pin_low(struct cec_pin *pin)
{
- pin->ops->low(pin->adap);
+ call_void_pin_op(pin, low);
cec_pin_update(pin, false, false);
}
static bool cec_pin_high(struct cec_pin *pin)
{
- pin->ops->high(pin->adap);
+ call_void_pin_op(pin, high);
return cec_pin_read(pin);
}
CEC_PIN_IRQ_UNCHANGED)) {
case CEC_PIN_IRQ_DISABLE:
if (irq_enabled) {
- pin->ops->disable_irq(adap);
+ call_void_pin_op(pin, disable_irq);
irq_enabled = false;
}
cec_pin_high(pin);
case CEC_PIN_IRQ_ENABLE:
if (irq_enabled)
break;
- pin->enable_irq_failed = !pin->ops->enable_irq(adap);
+ pin->enable_irq_failed = !call_pin_op(pin, enable_irq);
if (pin->enable_irq_failed) {
cec_pin_to_idle(pin);
hrtimer_start(&pin->timer, ns_to_ktime(0),
if (kthread_should_stop())
break;
}
- if (pin->ops->disable_irq && irq_enabled)
- pin->ops->disable_irq(adap);
+ if (irq_enabled)
+ call_void_pin_op(pin, disable_irq);
hrtimer_cancel(&pin->timer);
cec_pin_read(pin);
cec_pin_to_idle(pin);
seq_printf(file, "state: %s\n", states[pin->state].name);
seq_printf(file, "tx_bit: %d\n", pin->tx_bit);
seq_printf(file, "rx_bit: %d\n", pin->rx_bit);
- seq_printf(file, "cec pin: %d\n", pin->ops->read(adap));
+ seq_printf(file, "cec pin: %d\n", call_pin_op(pin, read));
seq_printf(file, "cec pin events dropped: %u\n",
pin->work_pin_events_dropped_cnt);
seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed);
pin->rx_data_bit_too_long_cnt = 0;
pin->rx_low_drive_cnt = 0;
pin->tx_low_drive_cnt = 0;
- if (pin->ops->status)
- pin->ops->status(adap, file);
+ call_void_pin_op(pin, status, file);
}
static int cec_pin_adap_monitor_all_enable(struct cec_adapter *adap,
{
struct cec_pin *pin = adap->pin;
- if (pin->ops->free)
+ if (pin && pin->ops->free)
pin->ops->free(adap);
adap->pin = NULL;
kfree(pin);
{
struct cec_pin *pin = adap->pin;
- if (pin->ops->received)
+ if (pin->ops->received && !adap->devnode.unregistered)
return pin->ops->received(adap, msg);
return -ENOMSG;
}
pr_info("cec-%s: " fmt, adap->name, ## arg); \
} while (0)
+#define call_op(adap, op, arg...) \
+ ((adap->ops->op && !adap->devnode.unregistered) ? \
+ adap->ops->op(adap, ## arg) : 0)
+
+#define call_void_op(adap, op, arg...) \
+ do { \
+ if (adap->ops->op && !adap->devnode.unregistered) \
+ adap->ops->op(adap, ## arg); \
+ } while (0)
+
/* devnode to cec_adapter */
#define to_cec_adapter(node) container_of(node, struct cec_adapter, devnode)