ACPI / MMC: PM: Unify fixing up device power
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 13 Jun 2022 18:36:06 +0000 (20:36 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 23 Jun 2022 18:53:55 +0000 (20:53 +0200)
Introduce acpi_device_fix_up_power_extended() for fixing up power of
a device having an ACPI companion in a manner that takes the device's
children into account and make the MMC code use it in two places
instead of walking the list of the device ACPI companion's children
directly.

This will help to eliminate the children list head from struct
acpi_device as it is redundant and it is used in questionable ways
in some places (in particular, locking is needed for walking the
list pointed to it safely, but it is often missing).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/acpi/device_pm.c
drivers/mmc/host/sdhci-acpi.c
drivers/mmc/host/sdhci-pci-core.c
include/acpi/acpi_bus.h

index 130b5f4a50a3d9d17f563e22eb70df0086a10555..9dce1245689ca2512240b20c6e544ce09b19621c 100644 (file)
@@ -369,6 +369,28 @@ int acpi_device_fix_up_power(struct acpi_device *device)
 }
 EXPORT_SYMBOL_GPL(acpi_device_fix_up_power);
 
+static int fix_up_power_if_applicable(struct acpi_device *adev, void *not_used)
+{
+       if (adev->status.present && adev->status.enabled)
+               acpi_device_fix_up_power(adev);
+
+       return 0;
+}
+
+/**
+ * acpi_device_fix_up_power_extended - Force device and its children into D0.
+ * @adev: Parent device object whose power state is to be fixed up.
+ *
+ * Call acpi_device_fix_up_power() for @adev and its children so long as they
+ * are reported as present and enabled.
+ */
+void acpi_device_fix_up_power_extended(struct acpi_device *adev)
+{
+       acpi_device_fix_up_power(adev);
+       acpi_dev_for_each_child(adev, fix_up_power_if_applicable, NULL);
+}
+EXPORT_SYMBOL_GPL(acpi_device_fix_up_power_extended);
+
 int acpi_device_update_power(struct acpi_device *device, int *state_p)
 {
        int state;
index c0350e9c03f3bdbcf66e18b47f8346bda1f4f4ae..4cca4c90769bc3ea625f23e0a7a3f842aba851fd 100644 (file)
@@ -775,8 +775,8 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        const struct sdhci_acpi_slot *slot;
-       struct acpi_device *device, *child;
        const struct dmi_system_id *id;
+       struct acpi_device *device;
        struct sdhci_acpi_host *c;
        struct sdhci_host *host;
        struct resource *iomem;
@@ -796,10 +796,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
        slot = sdhci_acpi_get_slot(device);
 
        /* Power on the SDHCI controller and its children */
-       acpi_device_fix_up_power(device);
-       list_for_each_entry(child, &device->children, node)
-               if (child->status.present && child->status.enabled)
-                       acpi_device_fix_up_power(child);
+       acpi_device_fix_up_power_extended(device);
 
        if (sdhci_acpi_byt_defer(dev))
                return -EPROBE_DEFER;
index ed53276f6ad90ba9cdfdd13495904696b324f894..622b7de96c7f679428a7f9d0107d8f81a52c8431 100644 (file)
@@ -1240,16 +1240,11 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
 #ifdef CONFIG_ACPI
 static void intel_mrfld_mmc_fix_up_power_slot(struct sdhci_pci_slot *slot)
 {
-       struct acpi_device *device, *child;
+       struct acpi_device *device;
 
        device = ACPI_COMPANION(&slot->chip->pdev->dev);
-       if (!device)
-               return;
-
-       acpi_device_fix_up_power(device);
-       list_for_each_entry(child, &device->children, node)
-               if (child->status.present && child->status.enabled)
-                       acpi_device_fix_up_power(child);
+       if (device)
+               acpi_device_fix_up_power_extended(device);
 }
 #else
 static inline void intel_mrfld_mmc_fix_up_power_slot(struct sdhci_pci_slot *slot) {}
index 76de1aa5d22135544ae9f20a503c2fc17994661b..54c5566df9fe1c8995fc6b8b8ef2b3c1dbf3293c 100644 (file)
@@ -524,6 +524,7 @@ const char *acpi_power_state_string(int state);
 int acpi_device_set_power(struct acpi_device *device, int state);
 int acpi_bus_init_power(struct acpi_device *device);
 int acpi_device_fix_up_power(struct acpi_device *device);
+void acpi_device_fix_up_power_extended(struct acpi_device *adev);
 int acpi_bus_update_power(acpi_handle handle, int *state_p);
 int acpi_device_update_power(struct acpi_device *device, int *state_p);
 bool acpi_bus_power_manageable(acpi_handle handle);