From: Matthew Garrett <mjg@redhat.com>
To: rjw@sisk.pl
Cc: linux-pm@lists.linux-foundation.org, jbarnes@virtuousgeek.org,
linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org,
stern@rowland.harvard.edu, shaohua.li@intel.com,
bjorn.helgaas@hp.com, Matthew Garrett <mjg@redhat.com>
Subject: [PATCH] pci: Updates to Rafael's runtime PCI PM patch set
Date: Mon, 9 Nov 2009 17:42:09 -0500 [thread overview]
Message-ID: <1257806529-6535-1-git-send-email-mjg@redhat.com> (raw)
In-Reply-To: <200910090051.50932.rjw@sisk.pl>
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
next prev parent reply other threads:[~2009-11-09 22:42 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-08 22:51 [RFC][PATCH 0/4] PCI run-time Power Management Rafael J. Wysocki
2009-10-08 22:52 ` [RFC][PATCH 1/4] PCI PM: Add function for checking PME status of devices Rafael J. Wysocki
2009-10-08 23:32 ` Bjorn Helgaas
2009-10-09 22:11 ` Rafael J. Wysocki
2009-10-08 22:53 ` [RFC][PATCH 2/4] PCI PM: PCIe PME root port service driver (rev. 3) Rafael J. Wysocki
2009-10-08 22:54 ` [RFC][PATCH 3/4] PCI / ACPI PM: Platform support for PCI PME wake-up (rev. 2) Rafael J. Wysocki
2009-10-09 11:23 ` Matthew Garrett
2009-10-09 23:05 ` Rafael J. Wysocki
2009-10-08 22:55 ` [RFC][PATCH 4/4] PCI PM: Run-time callbacks for PCI bus type Rafael J. Wysocki
2009-11-09 22:42 ` Matthew Garrett [this message]
2009-11-11 19:58 ` [PATCH] pci: Updates to Rafael's runtime PCI PM patch set Rafael J. Wysocki
2009-11-11 20:05 ` Matthew Garrett
2009-11-11 20:47 ` Rafael J. Wysocki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1257806529-6535-1-git-send-email-mjg@redhat.com \
--to=mjg@redhat.com \
--cc=bjorn.helgaas@hp.com \
--cc=jbarnes@virtuousgeek.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=rjw@sisk.pl \
--cc=shaohua.li@intel.com \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome