Merge branch 'for-5.12/intel-ish' into for-linus
- power management improvements for intel-ish driver from Zhang Lixu
This commit is contained in:
commit
7eb275f92d
|
@ -82,5 +82,6 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev);
|
|||
int ish_hw_start(struct ishtp_device *dev);
|
||||
void ish_device_disable(struct ishtp_device *dev);
|
||||
int ish_disable_dma(struct ishtp_device *dev);
|
||||
void ish_set_host_ready(struct ishtp_device *dev);
|
||||
|
||||
#endif /* _ISHTP_HW_ISH_H_ */
|
||||
|
|
|
@ -193,6 +193,33 @@ static void ish_clr_host_rdy(struct ishtp_device *dev)
|
|||
ish_reg_write(dev, IPC_REG_HOST_COMM, host_status);
|
||||
}
|
||||
|
||||
static bool ish_chk_host_rdy(struct ishtp_device *dev)
|
||||
{
|
||||
uint32_t host_status = ish_reg_read(dev, IPC_REG_HOST_COMM);
|
||||
|
||||
return (host_status & IPC_HOSTCOMM_READY_BIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* ish_set_host_ready() - reconfig ipc host registers
|
||||
* @dev: ishtp device pointer
|
||||
*
|
||||
* Set host to ready state
|
||||
* This API is called in some case:
|
||||
* fw is still on, but ipc is powered down.
|
||||
* such as OOB case.
|
||||
*
|
||||
* Return: 0 for success else error fault code
|
||||
*/
|
||||
void ish_set_host_ready(struct ishtp_device *dev)
|
||||
{
|
||||
if (ish_chk_host_rdy(dev))
|
||||
return;
|
||||
|
||||
ish_set_host_rdy(dev);
|
||||
set_host_ready(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* _ishtp_read_hdr() - Read message header
|
||||
* @dev: ISHTP device pointer
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Copyright (c) 2014-2016, Intel Corporation.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/kernel.h>
|
||||
|
@ -112,6 +113,42 @@ static inline bool ish_should_leave_d0i3(struct pci_dev *pdev)
|
|||
return !pm_resume_via_firmware() || pdev->device == CHV_DEVICE_ID;
|
||||
}
|
||||
|
||||
static int enable_gpe(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_ACPI
|
||||
acpi_status acpi_sts;
|
||||
struct acpi_device *adev;
|
||||
struct acpi_device_wakeup *wakeup;
|
||||
|
||||
adev = ACPI_COMPANION(dev);
|
||||
if (!adev) {
|
||||
dev_err(dev, "get acpi handle failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
wakeup = &adev->wakeup;
|
||||
|
||||
acpi_sts = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
|
||||
if (ACPI_FAILURE(acpi_sts)) {
|
||||
dev_err(dev, "enable ose_gpe failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -ENODEV;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void enable_pme_wake(struct pci_dev *pdev)
|
||||
{
|
||||
if ((pci_pme_capable(pdev, PCI_D0) ||
|
||||
pci_pme_capable(pdev, PCI_D3hot) ||
|
||||
pci_pme_capable(pdev, PCI_D3cold)) && !enable_gpe(&pdev->dev)) {
|
||||
pci_pme_active(pdev, true);
|
||||
dev_dbg(&pdev->dev, "ish ipc driver pme wake enabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ish_probe() - PCI driver probe callback
|
||||
* @pdev: pci device
|
||||
|
@ -180,6 +217,10 @@ static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
init_waitqueue_head(&ishtp->suspend_wait);
|
||||
init_waitqueue_head(&ishtp->resume_wait);
|
||||
|
||||
/* Enable PME for EHL */
|
||||
if (pdev->device == EHL_Ax_DEVICE_ID)
|
||||
enable_pme_wake(pdev);
|
||||
|
||||
ret = ish_init(ishtp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -219,11 +260,15 @@ static void __maybe_unused ish_resume_handler(struct work_struct *work)
|
|||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ish_resume_device);
|
||||
struct ishtp_device *dev = pci_get_drvdata(pdev);
|
||||
uint32_t fwsts = dev->ops->get_fw_status(dev);
|
||||
int ret;
|
||||
|
||||
if (ish_should_leave_d0i3(pdev) && !dev->suspend_flag) {
|
||||
if (ish_should_leave_d0i3(pdev) && !dev->suspend_flag
|
||||
&& IPC_IS_ISH_ILUP(fwsts)) {
|
||||
disable_irq_wake(pdev->irq);
|
||||
|
||||
ish_set_host_ready(dev);
|
||||
|
||||
ishtp_send_resume(dev);
|
||||
|
||||
/* Waiting to get resume response */
|
||||
|
@ -318,6 +363,13 @@ static int __maybe_unused ish_resume(struct device *device)
|
|||
struct pci_dev *pdev = to_pci_dev(device);
|
||||
struct ishtp_device *dev = pci_get_drvdata(pdev);
|
||||
|
||||
/* add this to finish power flow for EHL */
|
||||
if (dev->pdev->device == EHL_Ax_DEVICE_ID) {
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
enable_pme_wake(pdev);
|
||||
dev_dbg(dev->devc, "set power state to D0 for ehl\n");
|
||||
}
|
||||
|
||||
ish_resume_device = device;
|
||||
dev->resume_flag = 1;
|
||||
|
||||
|
|
Loading…
Reference in New Issue