Commit cb39dcdd authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Rafael J. Wysocki

ACPI / LPSS: add all LPSS devices to the specific power domain

Currently the LPSS devices are located in the different power domains depends
on LPSS_SAVE_CTX flag. We would like to use the specific power domain for all
LPSS devices.

The LPSS DMA controller has no knobs to control its power state. The specific
power domain implementation will handle this case. The patch does a preparation
for that.
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: default avatarScott Ashcroft <scott.ashcroft@talk21.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 206c5f60
......@@ -499,14 +499,15 @@ static void acpi_lpss_set_ltr(struct device *dev, s32 val)
/**
* acpi_lpss_save_ctx() - Save the private registers of LPSS device
* @dev: LPSS device
* @pdata: pointer to the private data of the LPSS device
*
* Most LPSS devices have private registers which may loose their context when
* the device is powered down. acpi_lpss_save_ctx() saves those registers into
* prv_reg_ctx array.
*/
static void acpi_lpss_save_ctx(struct device *dev)
static void acpi_lpss_save_ctx(struct device *dev,
struct lpss_private_data *pdata)
{
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
unsigned int i;
for (i = 0; i < LPSS_PRV_REG_COUNT; i++) {
......@@ -521,12 +522,13 @@ static void acpi_lpss_save_ctx(struct device *dev)
/**
* acpi_lpss_restore_ctx() - Restore the private registers of LPSS device
* @dev: LPSS device
* @pdata: pointer to the private data of the LPSS device
*
* Restores the registers that were previously stored with acpi_lpss_save_ctx().
*/
static void acpi_lpss_restore_ctx(struct device *dev)
static void acpi_lpss_restore_ctx(struct device *dev,
struct lpss_private_data *pdata)
{
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
unsigned int i;
/*
......@@ -549,23 +551,31 @@ static void acpi_lpss_restore_ctx(struct device *dev)
#ifdef CONFIG_PM_SLEEP
static int acpi_lpss_suspend_late(struct device *dev)
{
int ret = pm_generic_suspend_late(dev);
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
int ret;
ret = pm_generic_suspend_late(dev);
if (ret)
return ret;
acpi_lpss_save_ctx(dev);
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
acpi_lpss_save_ctx(dev, pdata);
return acpi_dev_suspend_late(dev);
}
static int acpi_lpss_resume_early(struct device *dev)
{
int ret = acpi_dev_resume_early(dev);
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
int ret;
ret = acpi_dev_resume_early(dev);
if (ret)
return ret;
acpi_lpss_restore_ctx(dev);
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
acpi_lpss_restore_ctx(dev, pdata);
return pm_generic_resume_early(dev);
}
#endif /* CONFIG_PM_SLEEP */
......@@ -573,23 +583,31 @@ static int acpi_lpss_resume_early(struct device *dev)
#ifdef CONFIG_PM_RUNTIME
static int acpi_lpss_runtime_suspend(struct device *dev)
{
int ret = pm_generic_runtime_suspend(dev);
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
int ret;
ret = pm_generic_runtime_suspend(dev);
if (ret)
return ret;
acpi_lpss_save_ctx(dev);
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
acpi_lpss_save_ctx(dev, pdata);
return acpi_dev_runtime_suspend(dev);
}
static int acpi_lpss_runtime_resume(struct device *dev)
{
int ret = acpi_dev_runtime_resume(dev);
struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
int ret;
ret = acpi_dev_runtime_resume(dev);
if (ret)
return ret;
acpi_lpss_restore_ctx(dev);
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
acpi_lpss_restore_ctx(dev, pdata);
return pm_generic_runtime_resume(dev);
}
#endif /* CONFIG_PM_RUNTIME */
......@@ -631,22 +649,21 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb,
return 0;
pdata = acpi_driver_data(adev);
if (!pdata || !pdata->mmio_base)
if (!pdata)
return 0;
if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) {
if (pdata->mmio_base &&
pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) {
dev_err(&pdev->dev, "MMIO size insufficient to access LTR\n");
return 0;
}
switch (action) {
case BUS_NOTIFY_BOUND_DRIVER:
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
pdev->dev.pm_domain = &acpi_lpss_pm_domain;
pdev->dev.pm_domain = &acpi_lpss_pm_domain;
break;
case BUS_NOTIFY_UNBOUND_DRIVER:
if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
pdev->dev.pm_domain = NULL;
pdev->dev.pm_domain = NULL;
break;
case BUS_NOTIFY_ADD_DEVICE:
if (pdata->dev_desc->flags & LPSS_LTR)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment