|
@@ -158,7 +158,7 @@ static bool mei_txe_aliveness_set(struct mei_device *dev, u32 req)
|
|
|
dev_dbg(&dev->pdev->dev, "Aliveness current=%d request=%d\n",
|
|
|
hw->aliveness, req);
|
|
|
if (do_req) {
|
|
|
- hw->recvd_aliveness = false;
|
|
|
+ dev->pg_event = MEI_PG_EVENT_WAIT;
|
|
|
mei_txe_br_reg_write(hw, SICR_HOST_ALIVENESS_REQ_REG, req);
|
|
|
}
|
|
|
return do_req;
|
|
@@ -213,6 +213,7 @@ static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected)
|
|
|
do {
|
|
|
hw->aliveness = mei_txe_aliveness_get(dev);
|
|
|
if (hw->aliveness == expected) {
|
|
|
+ dev->pg_event = MEI_PG_EVENT_IDLE;
|
|
|
dev_dbg(&dev->pdev->dev,
|
|
|
"aliveness settled after %d msecs\n", t);
|
|
|
return t;
|
|
@@ -223,6 +224,7 @@ static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected)
|
|
|
t += MSEC_PER_SEC / 5;
|
|
|
} while (t < SEC_ALIVENESS_WAIT_TIMEOUT);
|
|
|
|
|
|
+ dev->pg_event = MEI_PG_EVENT_IDLE;
|
|
|
dev_err(&dev->pdev->dev, "aliveness timed out\n");
|
|
|
return -ETIME;
|
|
|
}
|
|
@@ -249,19 +251,22 @@ static int mei_txe_aliveness_wait(struct mei_device *dev, u32 expected)
|
|
|
return 0;
|
|
|
|
|
|
mutex_unlock(&dev->device_lock);
|
|
|
- err = wait_event_timeout(hw->wait_aliveness,
|
|
|
- hw->recvd_aliveness, timeout);
|
|
|
+ err = wait_event_timeout(hw->wait_aliveness_resp,
|
|
|
+ dev->pg_event == MEI_PG_EVENT_RECEIVED, timeout);
|
|
|
mutex_lock(&dev->device_lock);
|
|
|
|
|
|
hw->aliveness = mei_txe_aliveness_get(dev);
|
|
|
ret = hw->aliveness == expected ? 0 : -ETIME;
|
|
|
|
|
|
if (ret)
|
|
|
- dev_err(&dev->pdev->dev, "aliveness timed out");
|
|
|
+ dev_warn(&dev->pdev->dev, "aliveness timed out = %ld aliveness = %d event = %d\n",
|
|
|
+ err, hw->aliveness, dev->pg_event);
|
|
|
else
|
|
|
- dev_dbg(&dev->pdev->dev, "aliveness settled after %d msecs\n",
|
|
|
- jiffies_to_msecs(timeout - err));
|
|
|
- hw->recvd_aliveness = false;
|
|
|
+ dev_dbg(&dev->pdev->dev, "aliveness settled after = %d msec aliveness = %d event = %d\n",
|
|
|
+ jiffies_to_msecs(timeout - err),
|
|
|
+ hw->aliveness, dev->pg_event);
|
|
|
+
|
|
|
+ dev->pg_event = MEI_PG_EVENT_IDLE;
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -291,6 +296,20 @@ static bool mei_txe_pg_is_enabled(struct mei_device *dev)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * mei_txe_pg_state - translate aliveness register value
|
|
|
+ * to the mei power gating state
|
|
|
+ *
|
|
|
+ * @dev: the device structure
|
|
|
+ *
|
|
|
+ * returns: MEI_PG_OFF if aliveness is on and MEI_PG_ON otherwise
|
|
|
+ */
|
|
|
+static inline enum mei_pg_state mei_txe_pg_state(struct mei_device *dev)
|
|
|
+{
|
|
|
+ struct mei_txe_hw *hw = to_txe_hw(dev);
|
|
|
+ return hw->aliveness ? MEI_PG_OFF : MEI_PG_ON;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* mei_txe_input_ready_interrupt_enable - sets the Input Ready Interrupt
|
|
|
*
|
|
@@ -972,9 +991,9 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id)
|
|
|
/* Clear the interrupt cause */
|
|
|
dev_dbg(&dev->pdev->dev,
|
|
|
"Aliveness Interrupt: Status: %d\n", hw->aliveness);
|
|
|
- hw->recvd_aliveness = true;
|
|
|
- if (waitqueue_active(&hw->wait_aliveness))
|
|
|
- wake_up(&hw->wait_aliveness);
|
|
|
+ dev->pg_event = MEI_PG_EVENT_RECEIVED;
|
|
|
+ if (waitqueue_active(&hw->wait_aliveness_resp))
|
|
|
+ wake_up(&hw->wait_aliveness_resp);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1024,6 +1043,8 @@ static const struct mei_hw_ops mei_txe_hw_ops = {
|
|
|
|
|
|
.host_is_ready = mei_txe_host_is_ready,
|
|
|
|
|
|
+ .pg_state = mei_txe_pg_state,
|
|
|
+
|
|
|
.hw_is_ready = mei_txe_hw_is_ready,
|
|
|
.hw_reset = mei_txe_hw_reset,
|
|
|
.hw_config = mei_txe_hw_config,
|
|
@@ -1069,7 +1090,7 @@ struct mei_device *mei_txe_dev_init(struct pci_dev *pdev)
|
|
|
|
|
|
hw = to_txe_hw(dev);
|
|
|
|
|
|
- init_waitqueue_head(&hw->wait_aliveness);
|
|
|
+ init_waitqueue_head(&hw->wait_aliveness_resp);
|
|
|
|
|
|
dev->ops = &mei_txe_hw_ops;
|
|
|
|