Re: PME via interrupt or SCI mechanism?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Sep 27, 2011 at 12:20:26AM +0200, Rafael J. Wysocki wrote:
> On Sunday, September 25, 2011, Rafael J. Wysocki wrote:
> > On Thursday, September 22, 2011, Sarah Sharp wrote:
> > > On Mon, Sep 19, 2011 at 11:43:33PM +0200, Rafael J. Wysocki wrote:
> > Without looking at the tables at the moment (I'll do that later),
> > I think that they are missing the information that GPE 0D is a wakeup
> > GPE for the xHCI device.
> 
> The DSDT appears to contain that information, so I'm not sure what's
> going on.  Perhaps you can put a debug printk into acpi_dev_run_wake()
> to see if that function is called for the xHCI controllers?

I put a printk in acpi_dev_run_wake(), and that shows up in the original
dmesg I sent:

Sep 22 10:47:09 talon kernel: [ 2026.211933] xhci_hcd 0000:00:14.0: acpi_pci_run_wake - enable dev wake
Sep 22 10:47:09 talon kernel: [ 2026.211936] acpi device:34: acpi_dev_run_wake - enable dev wake
Sep 22 10:47:09 talon kernel: [ 2026.211955] acpi device:34: acpi_dev_run_wake - return -19

The patch I've been using for adding debugging to the PCI and ACPI code
is attached.  I've been adding printks willy-nilly to try to understand
what's going on.

> > > In digging through the ACPI code, I noticed that acpi_bus_get_flags()
> > > looks for the ACPI methods _PR0 or _PS0 and sets
> > > device->flags.power_manageable to 1 if either of those methods are
> > > successfully invoked.  When I deassembled the ACPI tables, I didn't see
> > > either method for any of the USB host controllers in the system.
> 
> However, the power_manageable flag only indicates that the device can
> be put into low-power states through ACPI methods, it shouldn't have
> any effect on the wakeup settings.

Ok, good to know.

> > > device->flags.power_manageable is checked later when the runtime PM
> > > system attempts to put the PCI device into a lower state, but it seems
> > > to be ignored?  Is it supposed to be ignored?
> > 
> > Hmm, not really.  I'll have a look at that later.
> 
> It is used to decide whether or not to call __acpi_bus_set_power(), AFAICS.
> If it is not set, this function is not called, which is OK.  Still,
> devices for which it is not set may be put into low-power states and may
> generate wakeup signals.
> 
> For many PCI devices there are two possible power management interfaces,
> the native one and the ACPI-based one.  All of the modern devices support
> the native power management interface, so they can be put into low-power
> states even if the ACPI-based interface is missing for them (which is the
> case for your USB controllers).  For those devices, if the ACPI-based
> interface is not present, we simply use the native one only.

So if I understand you correctly, the kernel can use the native PCI power
management interface to put the PCI device into a lower power state...

> As far as wakeup is concerned, we should enable them to generate PME
> using the native interface and in addition to it we should use ACPI to
> enable the wakeup GPEs that are supposed to be triggered in response to
> the PME signals.

...but the kernel ACPI core will still be watching for the SCI that the
firmware generates on a PME wakeup?  Correct?

Is the native PCI power management interface you're referring to
implemented through the PCIe PME driver?  Because this particular host
controller is a PCIe device, not a PCI device.  I added some debug
statements to drivers/pci/pcie/pme.c, but the dmesg shows that none of
them got called.

> This apparently doesn't work correctly on your system and we need to figure
> out why.

Ok.  Do you have suggestions for any tests I can run or debugging
statements to add?  I'm really not an ACPI expert and I've been
basically fumbling in the dark.

Sarah Sharp
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 437ddbf..a8c7fad 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -370,20 +370,23 @@ int acpi_bus_update_power(acpi_handle handle, int *state_p)
 }
 EXPORT_SYMBOL_GPL(acpi_bus_update_power);
 
 
 bool acpi_bus_power_manageable(acpi_handle handle)
 {
 	struct acpi_device *device;
 	int result;
 
 	result = acpi_bus_get_device(handle, &device);
+	printk(KERN_DEBUG "%s - result %u, device->flags.power_manageable %u\n",
+			__func__, result,
+			result ? 0 : device->flags.power_manageable);
 	return result ? false : device->flags.power_manageable;
 }
 
 EXPORT_SYMBOL(acpi_bus_power_manageable);
 
 bool acpi_bus_can_wakeup(acpi_handle handle)
 {
 	struct acpi_device *device;
 	int result;
 
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 2ef0409..94173e0 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -63,20 +63,21 @@ static int acpi_pci_bind(struct acpi_device *device)
 {
 	acpi_status status;
 	acpi_handle handle;
 	struct pci_bus *bus;
 	struct pci_dev *dev;
 
 	dev = acpi_get_pci_dev(device->handle);
 	if (!dev)
 		return 0;
 
+	dev_dbg(&dev->dev, "%s\n", __func__);
 	pci_acpi_add_pm_notifier(device, dev);
 	if (device->wakeup.flags.run_wake)
 		device_set_run_wake(&dev->dev, true);
 
 	/*
 	 * Install the 'bind' function to facilitate callbacks for
 	 * children of the P2P bridge.
 	 */
 	if (dev->subordinate) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 7f9eba9..2acdf70 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -416,20 +416,21 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 {
 	struct acpi_prt_entry *entry;
 	int gsi;
 	u8 pin;
 	int triggering = ACPI_LEVEL_SENSITIVE;
 	int polarity = ACPI_ACTIVE_LOW;
 	char *link = NULL;
 	char link_desc[16];
 	int rc;
 
+	dev_dbg(&dev->dev, "%s\n", __func__);
 	pin = dev->pin;
 	if (!pin) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "No interrupt pin configured for device %s\n",
 				  pci_name(dev)));
 		return 0;
 	}
 
 	entry = acpi_pci_irq_lookup(dev, pin);
 	if (!entry) {
@@ -499,20 +500,21 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
 void __attribute__ ((weak)) acpi_unregister_gsi(u32 i)
 {
 }
 
 void acpi_pci_irq_disable(struct pci_dev *dev)
 {
 	struct acpi_prt_entry *entry;
 	int gsi;
 	u8 pin;
 
+	dev_dbg(&dev->dev, "%s\n", __func__);
 	pin = dev->pin;
 	if (!pin)
 		return;
 
 	entry = acpi_pci_irq_lookup(dev, pin);
 	if (!entry)
 		return;
 
 	if (entry->link)
 		gsi = acpi_pci_link_free_irq(entry->link);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 2672c79..b508392 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -216,35 +216,37 @@ static acpi_status acpi_pci_run_osc(acpi_handle handle,
 				    const u32 *capbuf, u32 *retval)
 {
 	struct acpi_osc_context context = {
 		.uuid_str = pci_osc_uuid_str,
 		.rev = 1,
 		.cap.length = 12,
 		.cap.pointer = (void *)capbuf,
 	};
 	acpi_status status;
 
+	printk(KERN_DEBUG "%s\n", __func__);
 	status = acpi_run_osc(handle, &context);
 	if (ACPI_SUCCESS(status)) {
 		*retval = *((u32 *)(context.ret.pointer + 8));
 		kfree(context.ret.pointer);
 	}
 	return status;
 }
 
 static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
 					u32 support,
 					u32 *control)
 {
 	acpi_status status;
 	u32 result, capbuf[3];
 
+	printk(KERN_DEBUG "%s\n", __func__);
 	support &= OSC_PCI_SUPPORT_MASKS;
 	support |= root->osc_support_set;
 
 	capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
 	capbuf[OSC_SUPPORT_TYPE] = support;
 	if (control) {
 		*control &= OSC_PCI_CONTROL_MASKS;
 		capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set;
 	} else {
 		/* Run _OSC query for all possible controls. */
@@ -258,20 +260,21 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
 			*control = result;
 	}
 	return status;
 }
 
 static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
 {
 	acpi_status status;
 	acpi_handle tmp;
 
+	printk(KERN_DEBUG "%s\n", __func__);
 	status = acpi_get_handle(root->device->handle, "_OSC", &tmp);
 	if (ACPI_FAILURE(status))
 		return status;
 	mutex_lock(&osc_lock);
 	status = acpi_pci_query_osc(root, flags, NULL);
 	mutex_unlock(&osc_lock);
 	return status;
 }
 
 struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
@@ -393,20 +396,21 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
  * _OSC bits the BIOS has granted control of, but its contents are meaningless
  * on failure.
  **/
 acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
 {
 	struct acpi_pci_root *root;
 	acpi_status status;
 	u32 ctrl, capbuf[3];
 	acpi_handle tmp;
 
+	printk(KERN_DEBUG "%s\n", __func__);
 	if (!mask)
 		return AE_BAD_PARAMETER;
 
 	ctrl = *mask & OSC_PCI_CONTROL_MASKS;
 	if ((ctrl & req) != req)
 		return AE_TYPE;
 
 	root = acpi_pci_find_root(handle);
 	if (!root)
 		return AE_NOT_EXIST;
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 449c556..e3e5f57 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -937,29 +937,37 @@ static int acpi_bus_get_flags(struct acpi_device *device)
 		if (ACPI_SUCCESS(status))
 			device->flags.ejectable = 1;
 	}
 
 	/* Presence of _LCK indicates 'lockable' */
 	status = acpi_get_handle(device->handle, "_LCK", &temp);
 	if (ACPI_SUCCESS(status))
 		device->flags.lockable = 1;
 
 	/* Power resources cannot be power manageable. */
-	if (device->device_type == ACPI_BUS_TYPE_POWER)
+	if (device->device_type == ACPI_BUS_TYPE_POWER) {
+		printk(KERN_DEBUG "%s - power resources are not "
+				"power manageable\n", __func__);
 		return 0;
+	}
 
 	/* Presence of _PS0|_PR0 indicates 'power manageable' */
 	status = acpi_get_handle(device->handle, "_PS0", &temp);
-	if (ACPI_FAILURE(status))
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_DEBUG "%s no _PS0\n", __func__);
 		status = acpi_get_handle(device->handle, "_PR0", &temp);
-	if (ACPI_SUCCESS(status))
+	}
+	if (ACPI_SUCCESS(status)) {
+		printk(KERN_DEBUG "%s _PR0\n", __func__);
 		device->flags.power_manageable = 1;
+	}
+	printk(KERN_DEBUG "%s no _PR0\n", __func__);
 
 	/* TBD: Performance management */
 
 	return 0;
 }
 
 static void acpi_device_get_busid(struct acpi_device *device)
 {
 	char bus_id[5] = { '?', 0 };
 	struct acpi_buffer buffer = { sizeof(bus_id), bus_id };
@@ -1227,20 +1235,21 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
 
 static int acpi_add_single_object(struct acpi_device **child,
 				  acpi_handle handle, int type,
 				  unsigned long long sta,
 				  struct acpi_bus_ops *ops)
 {
 	int result;
 	struct acpi_device *device;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
+	printk(KERN_DEBUG "%s\n", __func__);
 	device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
 	if (!device) {
 		printk(KERN_ERR PREFIX "Memory allocation error\n");
 		return -ENOMEM;
 	}
 
 	INIT_LIST_HEAD(&device->pnp.ids);
 	device->device_type = type;
 	device->handle = handle;
 	device->parent = acpi_bus_get_parent(handle);
@@ -1325,20 +1334,21 @@ end:
 			  ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING)
 
 static void acpi_bus_add_power_resource(acpi_handle handle)
 {
 	struct acpi_bus_ops ops = {
 		.acpi_op_add = 1,
 		.acpi_op_start = 1,
 	};
 	struct acpi_device *device = NULL;
 
+	printk(KERN_DEBUG "%s\n", __func__);
 	acpi_bus_get_device(handle, &device);
 	if (!device)
 		acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER,
 					ACPI_STA_DEFAULT, &ops);
 }
 
 static int acpi_bus_type_and_status(acpi_handle handle, int *type,
 				    unsigned long long *sta)
 {
 	acpi_status status;
@@ -1380,20 +1390,21 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type,
 static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
 				      void *context, void **return_value)
 {
 	struct acpi_bus_ops *ops = context;
 	int type;
 	unsigned long long sta;
 	struct acpi_device *device;
 	acpi_status status;
 	int result;
 
+	printk(KERN_DEBUG "%s\n", __func__);
 	result = acpi_bus_type_and_status(handle, &type, &sta);
 	if (result)
 		return AE_OK;
 
 	if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
 	    !(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
 		struct acpi_device_wakeup wakeup;
 		acpi_handle temp;
 
 		status = acpi_get_handle(handle, "_PRW", &temp);
@@ -1548,20 +1559,21 @@ EXPORT_SYMBOL_GPL(acpi_bus_trim);
 static int acpi_bus_scan_fixed(void)
 {
 	int result = 0;
 	struct acpi_device *device = NULL;
 	struct acpi_bus_ops ops;
 
 	memset(&ops, 0, sizeof(ops));
 	ops.acpi_op_add = 1;
 	ops.acpi_op_start = 1;
 
+	printk(KERN_DEBUG "%s\n", __func__);
 	/*
 	 * Enumerate all fixed-feature devices.
 	 */
 	if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
 		result = acpi_add_single_object(&device, NULL,
 						ACPI_BUS_TYPE_POWER_BUTTON,
 						ACPI_STA_DEFAULT,
 						&ops);
 	}
 
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index d36f41e..e7885fe 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -24,35 +24,39 @@ static DEFINE_MUTEX(pci_acpi_pm_notify_mtx);
 /**
  * pci_acpi_wake_bus - Wake-up notification handler for root buses.
  * @handle: ACPI handle of a device the notification is for.
  * @event: Type of the signaled event.
  * @context: PCI root bus to wake up devices on.
  */
 static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context)
 {
 	struct pci_bus *pci_bus = context;
 
-	if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus)
+	printk(KERN_DEBUG "%s\n", __func__);
+	if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus) {
+		dev_dbg(&pci_bus->self->dev, "%s\n", __func__);
 		pci_pme_wakeup_bus(pci_bus);
+	}
 }
 
 /**
  * pci_acpi_wake_dev - Wake-up notification handler for PCI devices.
  * @handle: ACPI handle of a device the notification is for.
  * @event: Type of the signaled event.
  * @context: PCI device object to wake up.
  */
 static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
 {
 	struct pci_dev *pci_dev = context;
 
 	if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) {
+		dev_dbg(&pci_dev->dev, "%s\n", __func__);
 		pci_wakeup_event(pci_dev);
 		pci_check_pme_status(pci_dev);
 		pm_runtime_resume(&pci_dev->dev);
 		if (pci_dev->subordinate)
 			pci_pme_wakeup_bus(pci_dev->subordinate);
 	}
 }
 
 /**
  * add_pm_notifier - Register PM notifier for given ACPI device.
@@ -136,20 +140,21 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
 }
 
 /**
  * pci_acpi_add_pm_notifier - Register PM notifier for given PCI device.
  * @dev: ACPI device to add the notifier for.
  * @pci_dev: PCI device to check for the PME status if an event is signaled.
  */
 acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
 				     struct pci_dev *pci_dev)
 {
+	dev_dbg(&pci_dev->dev, "%s\n", __func__);
 	return add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev);
 }
 
 /**
  * pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier.
  * @dev: ACPI device to remove the notifier from.
  */
 acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
 {
 	return remove_pm_notifier(dev, pci_acpi_wake_dev);
@@ -198,20 +203,28 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
 	case ACPI_STATE_D3_COLD:
 		return PCI_D3cold;
 	}
 	return PCI_POWER_ERROR;
 }
 
 static bool acpi_pci_power_manageable(struct pci_dev *dev)
 {
 	acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
 
+	if (handle) {
+		dev_dbg(&dev->dev, "%s - dev is%s power manageable\n",
+				__func__,
+				 acpi_bus_power_manageable(handle) ?
+				 "" : " not");
+	} else
+		dev_dbg(&dev->dev, "%s - dev is NOT power manageable\n",
+				__func__);
 	return handle ? acpi_bus_power_manageable(handle) : false;
 }
 
 static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
 	acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
 	acpi_handle tmp;
 	static const u8 state_conv[] = {
 		[PCI_D0] = ACPI_STATE_D0,
 		[PCI_D1] = ACPI_STATE_D1,
@@ -238,38 +251,48 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 		dev_printk(KERN_INFO, &dev->dev,
 				"power state changed by ACPI to D%d\n", state);
 
 	return error;
 }
 
 static bool acpi_pci_can_wakeup(struct pci_dev *dev)
 {
 	acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
 
+	if (handle)
+		dev_dbg(&dev->dev, "%s - dev can%s wakeup\n",
+				__func__,
+				 acpi_bus_can_wakeup(handle) ?
+				 "" : " not");
+	else
+		dev_dbg(&dev->dev, "%s - dev is can wakeup\n",
+				__func__);
 	return handle ? acpi_bus_can_wakeup(handle) : false;
 }
 
 static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
 {
 	while (bus->parent) {
 		if (!acpi_pm_device_sleep_wake(&bus->self->dev, enable))
 			return;
 		bus = bus->parent;
 	}
 
 	/* We have reached the root bus. */
 	if (bus->bridge)
 		acpi_pm_device_sleep_wake(bus->bridge, enable);
 }
 
 static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable)
 {
+	dev_dbg(&dev->dev, "%s - %s dev wake\n",
+			__func__, enable ? "enable" : "disable");
 	if (acpi_pci_can_wakeup(dev))
 		return acpi_pm_device_sleep_wake(&dev->dev, enable);
 
 	acpi_pci_propagate_wakeup_enable(dev->bus, enable);
 	return 0;
 }
 
 /**
  * acpi_dev_run_wake - Enable/disable wake-up for given device.
  * @phys_dev: Device to enable/disable the platform to wake-up the system for.
@@ -287,28 +310,31 @@ static int acpi_dev_run_wake(struct device *phys_dev, bool enable)
 	if (!device_run_wake(phys_dev))
 		return -EINVAL;
 
 	handle = DEVICE_ACPI_HANDLE(phys_dev);
 	if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) {
 		dev_dbg(phys_dev, "ACPI handle has no context in %s!\n",
 			__func__);
 		return -ENODEV;
 	}
 
+	dev_dbg(&dev->dev, "%s - %s dev wake\n",
+			__func__, enable ? "enable" : "disable");
 	if (enable) {
 		acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0);
 		acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
 	} else {
 		acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
 		acpi_disable_wakeup_device_power(dev);
 	}
 
+	dev_dbg(&dev->dev, "%s - return %i\n", __func__, error);
 	return error;
 }
 
 static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable)
 {
 	while (bus->parent) {
 		struct pci_dev *bridge = bus->self;
 
 		if (bridge->pme_interrupt)
 			return;
@@ -317,20 +343,22 @@ static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable)
 		bus = bus->parent;
 	}
 
 	/* We have reached the root bus. */
 	if (bus->bridge)
 		acpi_dev_run_wake(bus->bridge, enable);
 }
 
 static int acpi_pci_run_wake(struct pci_dev *dev, bool enable)
 {
+	dev_dbg(&dev->dev, "%s - %s dev wake\n",
+			__func__, enable ? "enable" : "disable");
 	if (dev->pme_interrupt)
 		return 0;
 
 	if (!acpi_dev_run_wake(&dev->dev, enable))
 		return 0;
 
 	acpi_pci_propagate_run_wake(dev->bus, enable);
 	return 0;
 }
 
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 08a95b3..2fcfa42 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -536,20 +536,22 @@ static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable)
  * -EIO if device does not support PCI PM or its PM capabilities register has a
  * wrong version, or device doesn't support the requested state.
  * 0 if device already is in the requested state.
  * 0 if device's power state has been successfully changed.
  */
 static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
 	u16 pmcsr;
 	bool need_restore = false;
 
+	dev_dbg(&dev->dev, "%s from %d to %d\n", __func__,
+			dev->current_state, state);
 	/* Check if we're already there */
 	if (dev->current_state == state)
 		return 0;
 
 	if (!dev->pm_cap)
 		return -EIO;
 
 	if (state < PCI_D0 || state > PCI_D3hot)
 		return -EINVAL;
 
@@ -652,24 +654,26 @@ void pci_update_current_state(struct pci_dev *dev, pci_power_t state)
 /**
  * pci_platform_power_transition - Use platform to change device power state
  * @dev: PCI device to handle.
  * @state: State to put the device into.
  */
 static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
 {
 	int error;
 
 	if (platform_pci_power_manageable(dev)) {
+		dev_dbg(&dev->dev, "%s - is power managable\n", __func__);
 		error = platform_pci_set_power_state(dev, state);
 		if (!error)
 			pci_update_current_state(dev, state);
 	} else {
+		dev_dbg(&dev->dev, "%s - is NOT power managable\n", __func__);
 		error = -ENODEV;
 		/* Fall back to PCI_D0 if native PM is not supported */
 		if (!dev->pm_cap)
 			dev->current_state = PCI_D0;
 	}
 
 	return error;
 }
 
 /**
@@ -726,22 +730,24 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 		 * If the device or the parent bridge do not support PCI PM,
 		 * ignore the request if we're doing anything other than putting
 		 * it into D0 (which would only happen on boot).
 		 */
 		return 0;
 
 	__pci_start_power_transition(dev, state);
 
 	/* This device is quirked not to be put into D3, so
 	   don't put it in D3 */
-	if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3))
+	if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) {
+		dev_dbg(&dev->dev, "%s - quirk: don't put in D3.\n", __func__);
 		return 0;
+	}
 
 	error = pci_raw_set_power_state(dev, state);
 
 	if (!__pci_complete_power_transition(dev, state))
 		error = 0;
 	/*
 	 * When aspm_policy is "powersave" this call ensures
 	 * that ASPM is configured.
 	 */
 	if (!error && dev->bus->self)
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index 0057344..22c2f68 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -56,24 +56,27 @@ struct pcie_pme_service_data {
  * @enable: Enable or disable the interrupt.
  */
 void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
 {
 	int rtctl_pos;
 	u16 rtctl;
 
 	rtctl_pos = pci_pcie_cap(dev) + PCI_EXP_RTCTL;
 
 	pci_read_config_word(dev, rtctl_pos, &rtctl);
-	if (enable)
+	if (enable) {
 		rtctl |= PCI_EXP_RTCTL_PMEIE;
-	else
+		dev_dbg(&dev->dev, "%s - Enabling PME interrupt.\n", __func__);
+	} else {
 		rtctl &= ~PCI_EXP_RTCTL_PMEIE;
+		dev_dbg(&dev->dev, "%s - Disabling PME interrupt.\n", __func__);
+	}
 	pci_write_config_word(dev, rtctl_pos, rtctl);
 }
 
 /**
  * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#.
  * @bus: PCI bus to scan.
  *
  * Scan given PCI bus and all buses under it for devices asserting PME#.
  */
 static bool pcie_pme_walk_bus(struct pci_bus *bus)
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index ce22f4a..5ecba68 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -431,20 +431,21 @@ static int suspend_common(struct device *dev, bool do_wakeup)
 	pci_disable_device(pci_dev);
 	return retval;
 }
 
 static int resume_common(struct device *dev, int event)
 {
 	struct pci_dev		*pci_dev = to_pci_dev(dev);
 	struct usb_hcd		*hcd = pci_get_drvdata(pci_dev);
 	int			retval;
 
+	dev_dbg(dev, "%s\n", __func__);
 	if (HCD_RH_RUNNING(hcd) ||
 			(hcd->shared_hcd &&
 			 HCD_RH_RUNNING(hcd->shared_hcd))) {
 		dev_dbg(dev, "can't resume, not suspended!\n");
 		return 0;
 	}
 
 	retval = pci_enable_device(pci_dev);
 	if (retval < 0) {
 		dev_err(dev, "can't re-enable after resume, %d!\n", retval);
@@ -479,20 +480,21 @@ static int hcd_pci_suspend(struct device *dev)
 {
 	return suspend_common(dev, device_may_wakeup(dev));
 }
 
 static int hcd_pci_suspend_noirq(struct device *dev)
 {
 	struct pci_dev		*pci_dev = to_pci_dev(dev);
 	struct usb_hcd		*hcd = pci_get_drvdata(pci_dev);
 	int			retval;
 
+	dev_dbg(&pci_dev->dev, "%s\n", __func__);
 	retval = check_root_hub_suspended(dev);
 	if (retval)
 		return retval;
 
 	pci_save_state(pci_dev);
 
 	/* If the root hub is dead rather than suspended, disallow remote
 	 * wakeup.  usb_hc_died() should ensure that both hosts are marked as
 	 * dying, so we only need to check the primary roothub.
 	 */
@@ -518,27 +520,29 @@ static int hcd_pci_suspend_noirq(struct device *dev)
 	powermac_set_asic(pci_dev, 0);
 	return retval;
 }
 
 static int hcd_pci_resume_noirq(struct device *dev)
 {
 	struct pci_dev		*pci_dev = to_pci_dev(dev);
 
 	powermac_set_asic(pci_dev, 1);
 
+	dev_dbg(dev, "%s\n", __func__);
 	/* Go back to D0 and disable remote wakeup */
 	pci_back_from_sleep(pci_dev);
 	return 0;
 }
 
 static int hcd_pci_resume(struct device *dev)
 {
+	dev_dbg(dev, "%s\n", __func__);
 	return resume_common(dev, PM_EVENT_RESUME);
 }
 
 static int hcd_pci_restore(struct device *dev)
 {
 	return resume_common(dev, PM_EVENT_RESTORE);
 }
 
 #else
 
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 723f823..383b248 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -786,20 +786,21 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
 #ifdef CONFIG_PM
 
 int xhci_bus_suspend(struct usb_hcd *hcd)
 {
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
 	int max_ports, port_index;
 	__le32 __iomem **port_array;
 	struct xhci_bus_state *bus_state;
 	unsigned long flags;
 
+	xhci_dbg(xhci, "%s\n", __func__);
 	max_ports = xhci_get_ports(hcd, &port_array);
 	bus_state = &xhci->bus_state[hcd_index(hcd)];
 
 	spin_lock_irqsave(&xhci->lock, flags);
 
 	if (hcd->self.root_hub->do_remote_wakeup) {
 		port_index = max_ports;
 		while (port_index--) {
 			if (bus_state->resume_done[port_index] != 0) {
 				spin_unlock_irqrestore(&xhci->lock, flags);
@@ -871,20 +872,21 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 
 int xhci_bus_resume(struct usb_hcd *hcd)
 {
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
 	int max_ports, port_index;
 	__le32 __iomem **port_array;
 	struct xhci_bus_state *bus_state;
 	u32 temp;
 	unsigned long flags;
 
+	xhci_dbg(xhci, "%s\n", __func__);
 	max_ports = xhci_get_ports(hcd, &port_array);
 	bus_state = &xhci->bus_state[hcd_index(hcd)];
 
 	if (time_before(jiffies, bus_state->next_statechange))
 		msleep(5);
 
 	spin_lock_irqsave(&xhci->lock, flags);
 	if (!HCD_HW_ACCESSIBLE(hcd)) {
 		spin_unlock_irqrestore(&xhci->lock, flags);
 		return -ESHUTDOWN;
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index cb16de2..fad2691 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -247,20 +247,21 @@ static void xhci_pci_remove(struct pci_dev *dev)
 	usb_hcd_pci_remove(dev);
 	kfree(xhci);
 }
 
 #ifdef CONFIG_PM
 static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 {
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
 	int	retval = 0;
 
+	xhci_dbg(xhci, "%s\n", __func__);
 	if (hcd->state != HC_STATE_SUSPENDED ||
 			xhci->shared_hcd->state != HC_STATE_SUSPENDED)
 		return -EINVAL;
 
 	retval = xhci_suspend(xhci);
 
 	return retval;
 }
 
 static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 3a0f695..a75cc7f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -689,20 +689,21 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
  * This is called when the machine transition into S3/S4 mode.
  *
  */
 int xhci_suspend(struct xhci_hcd *xhci)
 {
 	int			rc = 0;
 	struct usb_hcd		*hcd = xhci_to_hcd(xhci);
 	u32			command;
 	int			i;
 
+	xhci_dbg(xhci, "%s\n", __func__);
 	spin_lock_irq(&xhci->lock);
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
 	/* step 1: stop endpoint */
 	/* skipped assuming that port suspend has done */
 
 	/* step 2: clear Run/Stop bit */
 	command = xhci_readl(xhci, &xhci->op_regs->command);
 	command &= ~CMD_RUN;
 	xhci_writel(xhci, command, &xhci->op_regs->command);
@@ -744,20 +745,21 @@ int xhci_suspend(struct xhci_hcd *xhci)
  * This is called when the machine transition from S3/S4 mode.
  *
  */
 int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
 {
 	u32			command, temp = 0;
 	struct usb_hcd		*hcd = xhci_to_hcd(xhci);
 	struct usb_hcd		*secondary_hcd;
 	int			retval;
 
+	xhci_dbg(xhci, "%s\n", __func__);
 	/* Wait a bit if either of the roothubs need to settle from the
 	 * transition into bus suspend.
 	 */
 	if (time_before(jiffies, xhci->bus_state[0].next_statechange) ||
 			time_before(jiffies,
 				xhci->bus_state[1].next_statechange))
 		msleep(100);
 
 	spin_lock_irq(&xhci->lock);
 	if (xhci->quirks & XHCI_RESET_ON_RESUME)

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux