* transmit should be canceled.
                         */
                        err = wait_event_interruptible_timeout(adap->kthread_waitq,
+                               (adap->needs_hpd &&
+                                (!adap->is_configured && !adap->is_configuring)) ||
                                kthread_should_stop() ||
                                (!adap->transmitting &&
                                 !list_empty(&adap->transmit_queue)),
 
                mutex_lock(&adap->lock);
 
-               if (kthread_should_stop()) {
+               if ((adap->needs_hpd &&
+                    (!adap->is_configured && !adap->is_configuring)) ||
+                   kthread_should_stop()) {
                        cec_flush(adap);
                        goto unlock;
                }
                return -EINVAL;
        }
        if (!adap->is_configured && !adap->is_configuring) {
-               if (msg->msg[0] != 0xf0) {
+               if (adap->needs_hpd || msg->msg[0] != 0xf0) {
                        dprintk(1, "%s: adapter is unconfigured\n", __func__);
                        return -ENONET;
                }
  */
 static void cec_adap_unconfigure(struct cec_adapter *adap)
 {
-       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(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID));
        adap->log_addrs.log_addr_mask = 0;
        adap->is_configuring = false;
        adap->is_configured = false;
        if (phys_addr == adap->phys_addr || adap->devnode.unregistered)
                return;
 
+       dprintk(1, "new physical address %x.%x.%x.%x\n",
+               cec_phys_addr_exp(phys_addr));
        if (phys_addr == CEC_PHYS_ADDR_INVALID ||
            adap->phys_addr != CEC_PHYS_ADDR_INVALID) {
                adap->phys_addr = CEC_PHYS_ADDR_INVALID;
                if (adap->monitor_all_cnt)
                        WARN_ON(call_op(adap, adap_monitor_all_enable, false));
                mutex_lock(&adap->devnode.lock);
-               if (list_empty(&adap->devnode.fhs))
+               if (adap->needs_hpd || list_empty(&adap->devnode.fhs))
                        WARN_ON(adap->ops->adap_enable(adap, false));
                mutex_unlock(&adap->devnode.lock);
                if (phys_addr == CEC_PHYS_ADDR_INVALID)
        }
 
        mutex_lock(&adap->devnode.lock);
-       if (list_empty(&adap->devnode.fhs) &&
+       if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) &&
            adap->ops->adap_enable(adap, true)) {
                mutex_unlock(&adap->devnode.lock);
                return;
 
        if (adap->monitor_all_cnt &&
            call_op(adap, adap_monitor_all_enable, true)) {
-               if (list_empty(&adap->devnode.fhs))
+               if (adap->needs_hpd || list_empty(&adap->devnode.fhs))
                        WARN_ON(adap->ops->adap_enable(adap, false));
                mutex_unlock(&adap->devnode.lock);
                return;
 
                err = -EPERM;
        else if (adap->is_configuring)
                err = -ENONET;
-       else if (!adap->is_configured && msg.msg[0] != 0xf0)
+       else if (!adap->is_configured &&
+                (adap->needs_hpd || msg.msg[0] != 0xf0))
                err = -ENONET;
        else if (cec_is_busy(adap, fh))
                err = -EBUSY;
 
        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_lock(&devnode->lock);
        list_del(&fh->list);
        if (list_empty(&devnode->fhs) &&
+           !adap->needs_hpd &&
            adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
                WARN_ON(adap->ops->adap_enable(adap, false));
        }