static int mei_txe_pm_runtime_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct mei_device *dev; int ret; dev_dbg(&pdev->dev, "rpm: txe: runtime resume\n"); dev = pci_get_drvdata(pdev); if (!dev) return -ENODEV; mutex_lock(&dev->device_lock); mei_enable_interrupts(dev); ret = mei_txe_aliveness_set_sync(dev, 1); mutex_unlock(&dev->device_lock); dev_dbg(&pdev->dev, "rpm: txe: runtime resume ret = %d\n", ret); if (ret) schedule_work(&dev->reset_work); return ret; }
static int mei_txe_pm_runtime_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct mei_device *dev; int ret; dev_dbg(&pdev->dev, "rpm: txe: runtime suspend\n"); dev = pci_get_drvdata(pdev); if (!dev) return -ENODEV; mutex_lock(&dev->device_lock); if (mei_write_is_idle(dev)) ret = mei_txe_aliveness_set_sync(dev, 0); else ret = -EAGAIN; /* * If everything is okay we're about to enter PCI low * power state therefor we need to save and disable * the interrupts towards host. * However if device is not wakeable we cannot do that */ if (!ret && pci_dev_run_wake(pdev)) mei_txe_intr_save(dev); dev_dbg(&pdev->dev, "rpm: txe: runtime suspend ret=%d\n", ret); mutex_unlock(&dev->device_lock); return ret; }
/** * mei_txe_hw_start - start the hardware after reset * * @dev: the device structure * * Return: 0 on success an error code otherwise */ static int mei_txe_hw_start(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); int ret; u32 hisr; /* bring back interrupts */ mei_txe_intr_enable(dev); ret = mei_txe_readiness_wait(dev); if (ret < 0) { dev_err(dev->dev, "waiting for readiness failed\n"); return ret; } /* * If HISR.INT2_STS interrupt status bit is set then clear it. */ hisr = mei_txe_br_reg_read(hw, HISR_REG); if (hisr & HISR_INT_2_STS) mei_txe_br_reg_write(hw, HISR_REG, HISR_INT_2_STS); /* Clear the interrupt cause of OutputDoorbell */ clear_bit(TXE_INTR_OUT_DB_BIT, &hw->intr_cause); ret = mei_txe_aliveness_set_sync(dev, 1); if (ret < 0) { dev_err(dev->dev, "wait for aliveness failed ... bailing out\n"); return ret; } pm_runtime_set_active(dev->dev); /* enable input ready interrupts: * SEC_IPC_HOST_INT_MASK.IPC_INPUT_READY_INT_MASK */ mei_txe_input_ready_interrupt_enable(dev); /* Set the SICR_SEC_IPC_OUTPUT_STATUS.IPC_OUTPUT_READY bit */ mei_txe_output_ready_set(hw); /* Set bit SICR_HOST_IPC_READINESS.HOST_RDY */ mei_txe_readiness_set_host_rdy(dev); return 0; }
static int mei_txe_pm_runtime_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct mei_device *dev; int ret; dev_dbg(&pdev->dev, "rpm: txe: runtime suspend\n"); dev = pci_get_drvdata(pdev); if (!dev) return -ENODEV; mutex_lock(&dev->device_lock); if (mei_write_is_idle(dev)) ret = mei_txe_aliveness_set_sync(dev, 0); else ret = -EAGAIN; /* * If everything is okay we're about to enter PCI low * power state (D3) therefor we need to disable the * interrupts towards host. * However if device is not wakeable we do not enter * D-low state and we need to keep the interrupt kicking */ if (!ret && pci_dev_run_wake(pdev)) mei_disable_interrupts(dev); dev_dbg(&pdev->dev, "rpm: txe: runtime suspend ret=%d\n", ret); mutex_unlock(&dev->device_lock); if (ret && ret != -EAGAIN) schedule_work(&dev->reset_work); return ret; }