lkml.org 
[lkml]   [2009]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] pci: Updates to Rafael's runtime PCI PM patch set
    Date
    There's a few quirks with Rafael's PCI runtime PM code - this modifies
    them a little. The body of it is just porting it to my GPE rewrite, but
    it also moves the PCI binding earlier (otherwise acpi_pci_bind bails, since
    it's primarily intended for bridges), and also ensures that the pme bit
    gets set properly on hardware that requires it.

    Signed-off-by: Matthew Garrett <mjg@redhat.com>
    ---
    drivers/acpi/pci_bind.c | 12 ++++++------
    drivers/acpi/wakeup.c | 36 ------------------------------------
    drivers/pci/pci-acpi.c | 43 ++++++++++++++++---------------------------
    drivers/pci/pci-driver.c | 6 ++++++
    include/acpi/acpi_bus.h | 6 ------
    5 files changed, 28 insertions(+), 75 deletions(-)

    diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
    index d7baeca..d0086aa 100644
    --- a/drivers/acpi/pci_bind.c
    +++ b/drivers/acpi/pci_bind.c
    @@ -73,6 +73,12 @@ static int acpi_pci_bind(struct acpi_device *device)
    if (!dev)
    return 0;

    + if (device->wakeup.flags.valid) {
    + pci_acpi_add_device_pm_notifier(device, dev);
    + if (dev->subordinate)
    + pci_acpi_add_bus_pm_notifier(device, dev->subordinate);
    + }
    +
    /*
    * Install the 'bind' function to facilitate callbacks for
    * children of the P2P bridge.
    @@ -105,12 +111,6 @@ static int acpi_pci_bind(struct acpi_device *device)

    acpi_pci_irq_add_prt(device->handle, bus);

    - if (device->wakeup.flags.valid) {
    - pci_acpi_add_device_pm_notifier(device, dev);
    - if (dev->subordinate)
    - pci_acpi_add_bus_pm_notifier(device, dev->subordinate);
    - }
    -
    out:
    pci_dev_put(dev);
    return 0;
    diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
    index abdf349..be373cc 100644
    --- a/drivers/acpi/wakeup.c
    +++ b/drivers/acpi/wakeup.c
    @@ -98,42 +98,6 @@ void acpi_disable_wakeup_device(u8 sleep_state)

    #ifdef CONFIG_PM_WAKEUP
    /**
    - * acpi_device_run_wake - Enable/disable ACPI BIOS to generate wake-up events.
    - * @dev: Device to generate the wake-up events for.
    - * @enable: Desired action.
    - *
    - * If @enable is set, set up the GPE associated with @phys_dev to generate
    - * wake-up events at run time. If @enable is unset, disable the GPE associated
    - * with @phys_dev (unless it is marked as a run-wake device).
    - */
    -int acpi_device_run_wake(struct acpi_device *dev, bool enable)
    -{
    - if (!dev || !dev->wakeup.flags.valid)
    - return -EINVAL;
    -
    - if (enable) {
    - if (!dev->wakeup.state.enabled && !dev->wakeup.prepare_count)
    - return -EINVAL;
    -
    - acpi_set_gpe_type(dev->wakeup.gpe_device,
    - dev->wakeup.gpe_number,
    - ACPI_GPE_TYPE_WAKE_RUN);
    - acpi_enable_gpe(dev->wakeup.gpe_device,
    - dev->wakeup.gpe_number);
    - } else if (!dev->wakeup.flags.run_wake) {
    - acpi_set_gpe_type(dev->wakeup.gpe_device,
    - dev->wakeup.gpe_number,
    - ACPI_GPE_TYPE_WAKE);
    - acpi_disable_gpe(dev->wakeup.gpe_device,
    - dev->wakeup.gpe_number);
    - acpi_clear_gpe(dev->wakeup.gpe_device,
    - dev->wakeup.gpe_number, ACPI_NOT_ISR);
    - }
    -
    - return 0;
    -}
    -
    -/**
    * acpi_wakeup_gpes_shared - Check if given ACPI devices share a wake-up GPE.
    * @deva: First ACPI device to check.
    * @devb: Second ACPI device to check.
    diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
    index 51605c1..dae90cc 100644
    --- a/drivers/pci/pci-acpi.c
    +++ b/drivers/pci/pci-acpi.c
    @@ -35,12 +35,6 @@
    * notify handler for the root bridge, because the other devices will be checked
    * in the process of handling the root bridge wake-up.
    *
    - * Furthermore, if many devices share one wake-up GPE, we only need to install
    - * a notify handler for one of them as long as we know which devices to check
    - * in the process of handling the notification. The purpose of the data
    - * structures and helper functions below is to arrange things in accordance with
    - * these observations.
    - *
    * pci_acpi_runtime_notifiers is a list of struct pci_acpi_notifier_block
    * objects that each represent ACPI devices that have ACPI system notify
    * handlers installed. For each of them, there is a ACPI-based hotplug notifier
    @@ -63,7 +57,6 @@ struct pci_acpi_notifier_block
    void *hp_data;
    struct list_head pm_buses;
    struct list_head pm_devices;
    - int pm_enable_count;
    };

    struct pci_bus_notifier_entry
    @@ -102,7 +95,7 @@ static void pci_acpi_event_fn(acpi_handle handle, u32 event, void *data)

    mutex_lock(&pci_acpi_notifier_mtx);

    - if (event == ACPI_NOTIFY_DEVICE_WAKE && nb->pm_enable_count) {
    + if (event == ACPI_NOTIFY_DEVICE_WAKE) {
    if (!list_empty(&nb->pm_buses)) {
    struct pci_bus_notifier_entry *bne;

    @@ -316,10 +309,6 @@ acpi_status pci_acpi_add_device_pm_notifier(struct acpi_device *dev,
    if (bus_match(bne->bus, bus))
    goto out;

    - list_for_each_entry(dne, &nb->pm_devices, entry)
    - if (dne->dev == pci_dev)
    - goto out;
    -
    if (!new_dev_entry(pci_dev, &nb->pm_devices))
    status = AE_NO_MEMORY;
    goto out;
    @@ -385,10 +374,9 @@ acpi_status pci_acpi_remove_device_pm_notifier(struct acpi_device *dev,
    return AE_NOT_FOUND;

    found:
    - if (dne->enabled) {
    - if (!--nb->pm_enable_count)
    - acpi_device_run_wake(nb->dev, false);
    - }
    + if (dne->enabled)
    + acpi_unref_runtime_gpe(nb->dev->wakeup.gpe_device,
    + nb->dev->wakeup.gpe_number);
    list_del(&dne->entry);
    kfree(dne);

    @@ -523,9 +511,10 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev,

    found:
    if (bne->enable_count) {
    - nb->pm_enable_count -= bne->enable_count;
    - if (!nb->pm_enable_count)
    - acpi_device_run_wake(nb->dev, false);
    + int i;
    + for (i=bne->enable_count; i; i--)
    + acpi_unref_runtime_gpe(nb->dev->wakeup.gpe_device,
    + nb->dev->wakeup.gpe_number);
    }
    list_del(&bne->entry);
    kfree(bne);
    @@ -556,12 +545,12 @@ static int dev_run_wake(struct pci_acpi_notifier_block *nb,

    if (enable) {
    dne->enabled = true;
    - if (!nb->pm_enable_count++)
    - acpi_device_run_wake(nb->dev, true);
    + acpi_ref_runtime_gpe(nb->dev->wakeup.gpe_device,
    + nb->dev->wakeup.gpe_number);
    } else if (dne->enabled) {
    dne->enabled = false;
    - if (!--nb->pm_enable_count)
    - acpi_device_run_wake(nb->dev, false);
    + acpi_unref_runtime_gpe(nb->dev->wakeup.gpe_device,
    + nb->dev->wakeup.gpe_number);
    } else {
    error = -EALREADY;
    }
    @@ -582,12 +571,12 @@ static int bus_run_wake(struct pci_acpi_notifier_block *nb,

    if (enable) {
    bne->enable_count++;
    - if (!nb->pm_enable_count++)
    - acpi_device_run_wake(nb->dev, true);
    + acpi_ref_runtime_gpe(nb->dev->wakeup.gpe_device,
    + nb->dev->wakeup.gpe_number);
    } else if (bne->enable_count) {
    bne->enable_count--;
    - if (!--nb->pm_enable_count)
    - acpi_device_run_wake(nb->dev, false);
    + acpi_unref_runtime_gpe(nb->dev->wakeup.gpe_device,
    + nb->dev->wakeup.gpe_number);
    } else {
    error = -EALREADY;
    }
    diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
    index eb4f26a..d644db6 100644
    --- a/drivers/pci/pci-driver.c
    +++ b/drivers/pci/pci-driver.c
    @@ -967,6 +967,9 @@ static int pci_pm_runtime_suspend(struct device *dev)
    pci_prepare_to_sleep(pci_dev);
    }

    + if (pci_pme_capable(pci_dev, pci_target_state(pci_dev)))
    + pci_pme_active(pci_dev, true);
    +
    pci_platform_run_wake(pci_dev, true);

    return 0;
    @@ -980,6 +983,9 @@ static int pci_pm_runtime_resume(struct device *dev)
    if (!pm || !pm->runtime_resume)
    return -ENOSYS;

    + if (pci_pme_capable(pci_dev, pci_target_state(pci_dev)))
    + pci_pme_active(pci_dev, false);
    +
    pci_platform_run_wake(pci_dev, false);
    pci_pm_default_resume_early(pci_dev);
    pci_pm_default_resume(pci_dev);
    diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
    index 935036e..9541588 100644
    --- a/include/acpi/acpi_bus.h
    +++ b/include/acpi/acpi_bus.h
    @@ -389,7 +389,6 @@ struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
    #ifdef CONFIG_PM_WAKEUP
    int acpi_pm_device_sleep_state(struct device *, int *);
    int acpi_pm_device_sleep_wake(struct device *, bool);
    -int acpi_device_run_wake(struct acpi_device *, bool);
    bool acpi_wakeup_gpe_shared(struct acpi_device *, struct acpi_device *);
    #else /* !CONFIG_PM_WAKEUP */
    static inline int acpi_pm_device_sleep_state(struct device *d, int *p)
    @@ -404,11 +403,6 @@ static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
    return -ENODEV;
    }

    -static inline int acpi_device_run_wake(struct device *dev, bool enable)
    -{
    - return -ENODEV;
    -}
    -
    static inline bool acpi_wakeup_gpe_shared(struct acpi_device *a,
    struct acpi_device *b)
    {
    --
    1.6.5.2


    \
     
     \ /
      Last update: 2009-11-09 23:45    [W:0.038 / U:62.464 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site