Skip to content

Commit

Permalink
Merge branch 'pm-pci'
Browse files Browse the repository at this point in the history
Merge PCI device power management updates for 5.16-rc1:

 - Make the association of ACPI device objects with PCI devices more
   straightforward and simplify the code doing that for all devices
   in general (Rafael Wysocki).

 - Eliminate struct pci_platform_pm_ops and handle the both of its
   users (PCI and Intel MID) directly in the PCI bus code (Rafael
   Wysocki).

 - Simplify and clarify ACPI PCI device PM helpers (Rafael Wysocki).

 - Fix ordering of operations in pci_back_from_sleep() (Rafael
   Wysocki).

* pm-pci:
  PCI: PM: Fix ordering of operations in pci_back_from_sleep()
  PCI: PM: Do not call platform_pci_power_manageable() unnecessarily
  PCI: PM: Make pci_choose_state() call pci_target_state()
  PCI: PM: Rearrange pci_target_state()
  PCI: PM: Simplify acpi_pci_power_manageable()
  PCI: PM: Drop struct pci_platform_pm_ops
  PCI: ACPI: PM: Do not use pci_platform_pm_ops for ACPI
  PCI: PM: Do not use pci_platform_pm_ops for Intel MID PM
  ACPI: glue: Look for ACPI bus type only if ACPI companion is not known
  ACPI: glue: Drop cleanup callback from struct acpi_bus_type
  PCI: ACPI: Drop acpi_pci_bus
  • Loading branch information
rafaeljw committed Nov 2, 2021
2 parents 031eda1 + 6f9f0ee commit 1fec161
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 223 deletions.
34 changes: 22 additions & 12 deletions drivers/acpi/glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include <linux/rwsem.h>
#include <linux/acpi.h>
#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
#include <linux/platform_device.h>

#include "internal.h"
Expand Down Expand Up @@ -287,12 +289,13 @@ EXPORT_SYMBOL_GPL(acpi_unbind_one);

void acpi_device_notify(struct device *dev)
{
struct acpi_bus_type *type = acpi_get_bus_type(dev);
struct acpi_device *adev;
int ret;

ret = acpi_bind_one(dev, NULL);
if (ret) {
struct acpi_bus_type *type = acpi_get_bus_type(dev);

if (!type)
goto err;

Expand All @@ -304,17 +307,26 @@ void acpi_device_notify(struct device *dev)
ret = acpi_bind_one(dev, adev);
if (ret)
goto err;
}
adev = ACPI_COMPANION(dev);

if (dev_is_platform(dev))
acpi_configure_pmsi_domain(dev);
if (type->setup) {
type->setup(dev);
goto done;
}
} else {
adev = ACPI_COMPANION(dev);

if (dev_is_pci(dev)) {
pci_acpi_setup(dev, adev);
goto done;
} else if (dev_is_platform(dev)) {
acpi_configure_pmsi_domain(dev);
}
}

if (type && type->setup)
type->setup(dev);
else if (adev->handler && adev->handler->bind)
if (adev->handler && adev->handler->bind)
adev->handler->bind(dev);

done:
acpi_handle_debug(ACPI_HANDLE(dev), "Bound to device %s\n",
dev_name(dev));

Expand All @@ -327,14 +339,12 @@ void acpi_device_notify(struct device *dev)
void acpi_device_notify_remove(struct device *dev)
{
struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_bus_type *type;

if (!adev)
return;

type = acpi_get_bus_type(dev);
if (type && type->cleanup)
type->cleanup(dev);
if (dev_is_pci(dev))
pci_acpi_cleanup(dev, adev);
else if (adev->handler && adev->handler->unbind)
adev->handler->unbind(dev);

Expand Down
74 changes: 21 additions & 53 deletions drivers/pci/pci-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,7 @@ acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
* choose highest power _SxD or any lower power
*/

static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
{
int acpi_state, d_max;

Expand Down Expand Up @@ -965,22 +965,20 @@ int pci_dev_acpi_reset(struct pci_dev *dev, bool probe)
return 0;
}

static bool acpi_pci_power_manageable(struct pci_dev *dev)
bool acpi_pci_power_manageable(struct pci_dev *dev)
{
struct acpi_device *adev = ACPI_COMPANION(&dev->dev);

if (!adev)
return false;
return acpi_device_power_manageable(adev);
return adev && acpi_device_power_manageable(adev);
}

static bool acpi_pci_bridge_d3(struct pci_dev *dev)
bool acpi_pci_bridge_d3(struct pci_dev *dev)
{
const union acpi_object *obj;
struct acpi_device *adev;
struct pci_dev *rpdev;

if (!dev->is_hotplug_bridge)
if (acpi_pci_disabled || !dev->is_hotplug_bridge)
return false;

/* Assume D3 support if the bridge is power-manageable by ACPI. */
Expand Down Expand Up @@ -1008,7 +1006,7 @@ static bool acpi_pci_bridge_d3(struct pci_dev *dev)
return obj->integer.value == 1;
}

static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{
struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
static const u8 state_conv[] = {
Expand Down Expand Up @@ -1046,7 +1044,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
return error;
}

static pci_power_t acpi_pci_get_power_state(struct pci_dev *dev)
pci_power_t acpi_pci_get_power_state(struct pci_dev *dev)
{
struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
static const pci_power_t state_conv[] = {
Expand All @@ -1068,7 +1066,7 @@ static pci_power_t acpi_pci_get_power_state(struct pci_dev *dev)
return state_conv[state];
}

static void acpi_pci_refresh_power_state(struct pci_dev *dev)
void acpi_pci_refresh_power_state(struct pci_dev *dev)
{
struct acpi_device *adev = ACPI_COMPANION(&dev->dev);

Expand All @@ -1093,17 +1091,23 @@ static int acpi_pci_propagate_wakeup(struct pci_bus *bus, bool enable)
return 0;
}

static int acpi_pci_wakeup(struct pci_dev *dev, bool enable)
int acpi_pci_wakeup(struct pci_dev *dev, bool enable)
{
if (acpi_pci_disabled)
return 0;

if (acpi_pm_device_can_wakeup(&dev->dev))
return acpi_pm_set_device_wakeup(&dev->dev, enable);

return acpi_pci_propagate_wakeup(dev->bus, enable);
}

static bool acpi_pci_need_resume(struct pci_dev *dev)
bool acpi_pci_need_resume(struct pci_dev *dev)
{
struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
struct acpi_device *adev;

if (acpi_pci_disabled)
return false;

/*
* In some cases (eg. Samsung 305V4A) leaving a bridge in suspend over
Expand All @@ -1115,6 +1119,7 @@ static bool acpi_pci_need_resume(struct pci_dev *dev)
if (pci_is_bridge(dev) && acpi_target_system_state() != ACPI_STATE_S0)
return true;

adev = ACPI_COMPANION(&dev->dev);
if (!adev || !acpi_device_power_manageable(adev))
return false;

Expand All @@ -1128,17 +1133,6 @@ static bool acpi_pci_need_resume(struct pci_dev *dev)
return !!adev->power.flags.dsw_present;
}

static const struct pci_platform_pm_ops acpi_pci_platform_pm = {
.bridge_d3 = acpi_pci_bridge_d3,
.is_manageable = acpi_pci_power_manageable,
.set_state = acpi_pci_set_power_state,
.get_state = acpi_pci_get_power_state,
.refresh_state = acpi_pci_refresh_power_state,
.choose_state = acpi_pci_choose_state,
.set_wakeup = acpi_pci_wakeup,
.need_resume = acpi_pci_need_resume,
};

void acpi_pci_add_bus(struct pci_bus *bus)
{
union acpi_object *obj;
Expand Down Expand Up @@ -1356,13 +1350,9 @@ static void pci_acpi_set_external_facing(struct pci_dev *dev)
dev->external_facing = 1;
}

static void pci_acpi_setup(struct device *dev)
void pci_acpi_setup(struct device *dev, struct acpi_device *adev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct acpi_device *adev = ACPI_COMPANION(dev);

if (!adev)
return;

pci_acpi_optimize_delay(pci_dev, adev->handle);
pci_acpi_set_external_facing(pci_dev);
Expand All @@ -1386,14 +1376,10 @@ static void pci_acpi_setup(struct device *dev)
acpi_device_power_add_dependent(adev, dev);
}

static void pci_acpi_cleanup(struct device *dev)
void pci_acpi_cleanup(struct device *dev, struct acpi_device *adev)
{
struct acpi_device *adev = ACPI_COMPANION(dev);
struct pci_dev *pci_dev = to_pci_dev(dev);

if (!adev)
return;

pci_acpi_remove_edr_notifier(pci_dev);
pci_acpi_remove_pm_notifier(adev);
if (adev->wakeup.flags.valid) {
Expand All @@ -1405,20 +1391,6 @@ static void pci_acpi_cleanup(struct device *dev)
}
}

static bool pci_acpi_bus_match(struct device *dev)
{
return dev_is_pci(dev);
}

static struct acpi_bus_type acpi_pci_bus = {
.name = "PCI",
.match = pci_acpi_bus_match,
.find_companion = acpi_pci_find_companion,
.setup = pci_acpi_setup,
.cleanup = pci_acpi_cleanup,
};


static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);

/**
Expand Down Expand Up @@ -1460,8 +1432,6 @@ struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)

static int __init acpi_pci_init(void)
{
int ret;

if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) {
pr_info("ACPI FADT declares the system doesn't support MSI, so disable it\n");
pci_no_msi();
Expand All @@ -1472,11 +1442,9 @@ static int __init acpi_pci_init(void)
pcie_no_aspm();
}

ret = register_acpi_bus_type(&acpi_pci_bus);
if (ret)
if (acpi_pci_disabled)
return 0;

pci_set_platform_pm(&acpi_pci_platform_pm);
acpi_pci_slot_init();
acpiphp_init();

Expand Down
37 changes: 8 additions & 29 deletions drivers/pci/pci-mid.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,23 @@

#include "pci.h"

static bool mid_pci_power_manageable(struct pci_dev *dev)
static bool pci_mid_pm_enabled __read_mostly;

bool pci_use_mid_pm(void)
{
return true;
return pci_mid_pm_enabled;
}

static int mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state)
int mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state)
{
return intel_mid_pci_set_power_state(pdev, state);
}

static pci_power_t mid_pci_get_power_state(struct pci_dev *pdev)
pci_power_t mid_pci_get_power_state(struct pci_dev *pdev)
{
return intel_mid_pci_get_power_state(pdev);
}

static pci_power_t mid_pci_choose_state(struct pci_dev *pdev)
{
return PCI_D3hot;
}

static int mid_pci_wakeup(struct pci_dev *dev, bool enable)
{
return 0;
}

static bool mid_pci_need_resume(struct pci_dev *dev)
{
return false;
}

static const struct pci_platform_pm_ops mid_pci_platform_pm = {
.is_manageable = mid_pci_power_manageable,
.set_state = mid_pci_set_power_state,
.get_state = mid_pci_get_power_state,
.choose_state = mid_pci_choose_state,
.set_wakeup = mid_pci_wakeup,
.need_resume = mid_pci_need_resume,
};

/*
* This table should be in sync with the one in
* arch/x86/platform/intel-mid/pwr.c.
Expand All @@ -71,7 +49,8 @@ static int __init mid_pci_init(void)

id = x86_match_cpu(lpss_cpu_ids);
if (id)
pci_set_platform_pm(&mid_pci_platform_pm);
pci_mid_pm_enabled = true;

return 0;
}
arch_initcall(mid_pci_init);
Loading

0 comments on commit 1fec161

Please sign in to comment.