hcsr = mei_hcsr_read(dev);
dev->hbuf_depth = (hcsr & H_CBD) >> 24;
- hw->pg_state = MEI_PG_OFF;
-
reg = 0;
pci_read_config_dword(pdev, PCI_CFG_HFS_1, ®);
hw->d0i3_supported =
((reg & PCI_CFG_HFS_1_D0I3_MSK) == PCI_CFG_HFS_1_D0I3_MSK);
+
+ hw->pg_state = MEI_PG_OFF;
+ if (hw->d0i3_supported) {
+ reg = mei_me_d0i3c_read(dev);
+ if (reg & H_D0I3C_I3)
+ hw->pg_state = MEI_PG_ON;
+ }
}
/**
* @dev: the device structure
* @intr_enable: if interrupt should be enabled after reset.
*
- * Return: always 0
+ * Return: 0 on success an error code otherwise
*/
static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
{
- u32 hcsr = mei_hcsr_read(dev);
+ struct mei_me_hw *hw = to_me_hw(dev);
+ int ret;
+ u32 hcsr;
+
+ if (intr_enable) {
+ mei_me_intr_enable(dev);
+ if (hw->d0i3_supported) {
+ ret = mei_me_d0i3_exit_sync(dev);
+ if (ret)
+ return ret;
+ }
+ }
+ hcsr = mei_hcsr_read(dev);
/* H_RST may be found lit before reset is started,
* for example if preceding reset flow hasn't completed.
* In that case asserting H_RST will be ignored, therefore
hcsr |= H_RST | H_IG | H_CSR_IS_MASK;
- if (intr_enable)
- hcsr |= H_CSR_IE_MASK;
- else
+ if (!intr_enable)
hcsr &= ~H_CSR_IE_MASK;
dev->recvd_hw_ready = false;
if ((hcsr & H_RDY) == H_RDY)
dev_warn(dev->dev, "H_RDY is not cleared 0x%08X", hcsr);
- if (intr_enable == false)
+ if (!intr_enable) {
mei_me_hw_reset_release(dev);
-
+ if (hw->d0i3_supported) {
+ ret = mei_me_d0i3_enter(dev);
+ if (ret)
+ return ret;
+ }
+ }
return 0;
}