From owner-svn-src-head@FreeBSD.ORG Tue Aug 17 15:44:52 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E9C54106564A; Tue, 17 Aug 2010 15:44:52 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D7CA78FC1A; Tue, 17 Aug 2010 15:44:52 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7HFiqe2037056; Tue, 17 Aug 2010 15:44:52 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7HFiqfF037045; Tue, 17 Aug 2010 15:44:52 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201008171544.o7HFiqfF037045@svn.freebsd.org> From: John Baldwin Date: Tue, 17 Aug 2010 15:44:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r211430 - in head/sys/dev: acpica pci X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Aug 2010 15:44:53 -0000 Author: jhb Date: Tue Aug 17 15:44:52 2010 New Revision: 211430 URL: http://svn.freebsd.org/changeset/base/211430 Log: Add a new method to the PCI bridge interface, PCIB_POWER_FOR_SLEEP(). This method is used by the PCI bus driver to query the power management system to determine the proper device state to be used for a device during suspend and resume. For the ACPI PCI bridge drivers this calls acpi_device_pwr_for_sleep(). This removes ACPI-specific knowledge from the PCI and PCI-PCI bridge drivers. Reviewed by: jkim Modified: head/sys/dev/acpica/acpi.c head/sys/dev/acpica/acpi_pcib.c head/sys/dev/acpica/acpi_pcib_acpi.c head/sys/dev/acpica/acpi_pcib_pci.c head/sys/dev/acpica/acpi_pcibvar.h head/sys/dev/acpica/acpivar.h head/sys/dev/pci/pci.c head/sys/dev/pci/pci_pci.c head/sys/dev/pci/pci_private.h head/sys/dev/pci/pcib_if.m Modified: head/sys/dev/acpica/acpi.c ============================================================================== --- head/sys/dev/acpica/acpi.c Tue Aug 17 15:07:23 2010 (r211429) +++ head/sys/dev/acpica/acpi.c Tue Aug 17 15:44:52 2010 (r211430) @@ -129,8 +129,6 @@ static char *acpi_device_id_probe(device static ACPI_STATUS acpi_device_eval_obj(device_t bus, device_t dev, ACPI_STRING pathname, ACPI_OBJECT_LIST *parameters, ACPI_BUFFER *ret); -static int acpi_device_pwr_for_sleep(device_t bus, device_t dev, - int *dstate); static ACPI_STATUS acpi_device_scan_cb(ACPI_HANDLE h, UINT32 level, void *context, void **retval); static ACPI_STATUS acpi_device_scan_children(device_t bus, device_t dev, @@ -1415,7 +1413,7 @@ acpi_device_eval_obj(device_t bus, devic return (AcpiEvaluateObject(h, pathname, parameters, ret)); } -static int +int acpi_device_pwr_for_sleep(device_t bus, device_t dev, int *dstate) { struct acpi_softc *sc; Modified: head/sys/dev/acpica/acpi_pcib.c ============================================================================== --- head/sys/dev/acpica/acpi_pcib.c Tue Aug 17 15:07:23 2010 (r211429) +++ head/sys/dev/acpica/acpi_pcib.c Tue Aug 17 15:44:52 2010 (r211430) @@ -275,3 +275,14 @@ out: return_VALUE (interrupt); } + +int +acpi_pcib_power_for_sleep(device_t pcib, device_t dev, int *pstate) +{ + device_t acpi_dev; + + acpi_dev = devclass_get_device(devclass_find("acpi"), 0); + acpi_device_pwr_for_sleep(acpi_dev, dev, pstate); + return (0); +} + Modified: head/sys/dev/acpica/acpi_pcib_acpi.c ============================================================================== --- head/sys/dev/acpica/acpi_pcib_acpi.c Tue Aug 17 15:07:23 2010 (r211429) +++ head/sys/dev/acpica/acpi_pcib_acpi.c Tue Aug 17 15:44:52 2010 (r211430) @@ -116,6 +116,7 @@ static device_method_t acpi_pcib_acpi_me DEVMETHOD(pcib_alloc_msix, acpi_pcib_alloc_msix), DEVMETHOD(pcib_release_msix, pcib_release_msix), DEVMETHOD(pcib_map_msi, acpi_pcib_map_msi), + DEVMETHOD(pcib_power_for_sleep, acpi_pcib_power_for_sleep), {0, 0} }; Modified: head/sys/dev/acpica/acpi_pcib_pci.c ============================================================================== --- head/sys/dev/acpica/acpi_pcib_pci.c Tue Aug 17 15:07:23 2010 (r211429) +++ head/sys/dev/acpica/acpi_pcib_pci.c Tue Aug 17 15:44:52 2010 (r211430) @@ -80,6 +80,7 @@ static device_method_t acpi_pcib_pci_met /* pcib interface */ DEVMETHOD(pcib_route_interrupt, acpi_pcib_pci_route_interrupt), + DEVMETHOD(pcib_power_for_sleep, acpi_pcib_power_for_sleep), {0, 0} }; Modified: head/sys/dev/acpica/acpi_pcibvar.h ============================================================================== --- head/sys/dev/acpica/acpi_pcibvar.h Tue Aug 17 15:07:23 2010 (r211429) +++ head/sys/dev/acpica/acpi_pcibvar.h Tue Aug 17 15:44:52 2010 (r211430) @@ -38,6 +38,8 @@ int acpi_pci_link_route_interrupt(device int acpi_pcib_attach(device_t bus, ACPI_BUFFER *prt, int busno); int acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin, ACPI_BUFFER *prtbuf); +int acpi_pcib_power_for_sleep(device_t pcib, device_t dev, + int *pstate); #endif /* _KERNEL */ Modified: head/sys/dev/acpica/acpivar.h ============================================================================== --- head/sys/dev/acpica/acpivar.h Tue Aug 17 15:07:23 2010 (r211429) +++ head/sys/dev/acpica/acpivar.h Tue Aug 17 15:44:52 2010 (r211430) @@ -393,6 +393,8 @@ EVENTHANDLER_DECLARE(acpi_wakeup_event, /* Device power control. */ ACPI_STATUS acpi_pwr_wake_enable(ACPI_HANDLE consumer, int enable); ACPI_STATUS acpi_pwr_switch_consumer(ACPI_HANDLE consumer, int state); +int acpi_device_pwr_for_sleep(device_t bus, device_t dev, + int *dstate); /* Misc. */ static __inline struct acpi_softc * Modified: head/sys/dev/pci/pci.c ============================================================================== --- head/sys/dev/pci/pci.c Tue Aug 17 15:07:23 2010 (r211429) +++ head/sys/dev/pci/pci.c Tue Aug 17 15:44:52 2010 (r211430) @@ -69,13 +69,6 @@ __FBSDID("$FreeBSD$"); #include "pcib_if.h" #include "pci_if.h" -#ifdef __HAVE_ACPI -#include -#include "acpi_if.h" -#else -#define ACPI_PWR_FOR_SLEEP(x, y, z) -#endif - static pci_addr_t pci_mapbase(uint64_t mapreg); static const char *pci_maptype(uint64_t mapreg); static int pci_mapsize(uint64_t testval); @@ -2914,16 +2907,13 @@ int pci_suspend(device_t dev) { int dstate, error, i, numdevs; - device_t acpi_dev, child, *devlist; + device_t child, *devlist, pcib; struct pci_devinfo *dinfo; /* * Save the PCI configuration space for each child and set the * device in the appropriate power state for this sleep state. */ - acpi_dev = NULL; - if (pci_do_power_resume) - acpi_dev = devclass_get_device(devclass_find("acpi"), 0); if ((error = device_get_children(dev, &devlist, &numdevs)) != 0) return (error); for (i = 0; i < numdevs; i++) { @@ -2940,22 +2930,23 @@ pci_suspend(device_t dev) } /* - * Always set the device to D3. If ACPI suggests a different - * power state, use it instead. If ACPI is not present, the - * firmware is responsible for managing device power. Skip - * children who aren't attached since they are powered down - * separately. Only manage type 0 devices for now. + * Always set the device to D3. If the firmware suggests a + * different power state, use it instead. If power management + * is not present, the firmware is responsible for managing + * device power. Skip children who aren't attached since they + * are powered down separately. Only manage type 0 devices + * for now. */ - for (i = 0; acpi_dev && i < numdevs; i++) { + pcib = device_get_parent(dev); + for (i = 0; pci_do_power_resume && i < numdevs; i++) { child = devlist[i]; dinfo = (struct pci_devinfo *) device_get_ivars(child); + dstate = PCI_POWERSTATE_D3; if (device_is_attached(child) && (dinfo->cfg.hdrtype & PCIM_HDRTYPE) == - PCIM_HDRTYPE_NORMAL) { - dstate = PCI_POWERSTATE_D3; - ACPI_PWR_FOR_SLEEP(acpi_dev, child, &dstate); + PCIM_HDRTYPE_NORMAL && + PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0) pci_set_powerstate(child, dstate); - } } free(devlist, M_TEMP); return (0); @@ -2965,31 +2956,29 @@ int pci_resume(device_t dev) { int i, numdevs, error; - device_t acpi_dev, child, *devlist; + device_t child, *devlist, pcib; struct pci_devinfo *dinfo; /* * Set each child to D0 and restore its PCI configuration space. */ - acpi_dev = NULL; - if (pci_do_power_resume) - acpi_dev = devclass_get_device(devclass_find("acpi"), 0); if ((error = device_get_children(dev, &devlist, &numdevs)) != 0) return (error); + pcib = device_get_parent(dev); for (i = 0; i < numdevs; i++) { /* - * Notify ACPI we're going to D0 but ignore the result. If - * ACPI is not present, the firmware is responsible for - * managing device power. Only manage type 0 devices for now. + * Notify power managment we're going to D0 but ignore + * the result. If power management is not present, + * the firmware is responsible for managing device + * power. Only manage type 0 devices for now. */ child = devlist[i]; dinfo = (struct pci_devinfo *) device_get_ivars(child); - if (acpi_dev && device_is_attached(child) && + if (device_is_attached(child) && (dinfo->cfg.hdrtype & PCIM_HDRTYPE) == - PCIM_HDRTYPE_NORMAL) { - ACPI_PWR_FOR_SLEEP(acpi_dev, child, NULL); + PCIM_HDRTYPE_NORMAL && + PCIB_POWER_FOR_SLEEP(pcib, dev, NULL) == 0) pci_set_powerstate(child, PCI_POWERSTATE_D0); - } /* Now the device is powered up, restore its config space. */ pci_cfg_restore(child, dinfo); Modified: head/sys/dev/pci/pci_pci.c ============================================================================== --- head/sys/dev/pci/pci_pci.c Tue Aug 17 15:07:23 2010 (r211429) +++ head/sys/dev/pci/pci_pci.c Tue Aug 17 15:44:52 2010 (r211430) @@ -48,22 +48,16 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include "pcib_if.h" -#ifdef __HAVE_ACPI -#include -#include "acpi_if.h" -#else -#define ACPI_PWR_FOR_SLEEP(x, y, z) -#endif - -extern int pci_do_power_resume; - static int pcib_probe(device_t dev); static int pcib_suspend(device_t dev); static int pcib_resume(device_t dev); +static int pcib_power_for_sleep(device_t pcib, device_t dev, + int *pstate); static device_method_t pcib_methods[] = { /* Device interface */ @@ -95,6 +89,7 @@ static device_method_t pcib_methods[] = DEVMETHOD(pcib_alloc_msix, pcib_alloc_msix), DEVMETHOD(pcib_release_msix, pcib_release_msix), DEVMETHOD(pcib_map_msi, pcib_map_msi), + DEVMETHOD(pcib_power_for_sleep, pcib_power_for_sleep), { 0, 0 } }; @@ -447,18 +442,16 @@ pcib_attach(device_t dev) int pcib_suspend(device_t dev) { - device_t acpi_dev; + device_t pcib; int dstate, error; pcib_cfg_save(device_get_softc(dev)); error = bus_generic_suspend(dev); if (error == 0 && pci_do_power_resume) { - acpi_dev = devclass_get_device(devclass_find("acpi"), 0); - if (acpi_dev != NULL) { - dstate = PCI_POWERSTATE_D3; - ACPI_PWR_FOR_SLEEP(acpi_dev, dev, &dstate); + dstate = PCI_POWERSTATE_D3; + pcib = device_get_parent(device_get_parent(dev)); + if (PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0) pci_set_powerstate(dev, dstate); - } } return (error); } @@ -466,14 +459,12 @@ pcib_suspend(device_t dev) int pcib_resume(device_t dev) { - device_t acpi_dev; + device_t pcib; if (pci_do_power_resume) { - acpi_dev = devclass_get_device(devclass_find("acpi"), 0); - if (acpi_dev != NULL) { - ACPI_PWR_FOR_SLEEP(acpi_dev, dev, NULL); + pcib = device_get_parent(device_get_parent(dev)); + if (PCIB_POWER_FOR_SLEEP(pcib, dev, NULL) == 0) pci_set_powerstate(dev, PCI_POWERSTATE_D0); - } } pcib_cfg_restore(device_get_softc(dev)); return (bus_generic_resume(dev)); @@ -790,6 +781,16 @@ pcib_map_msi(device_t pcib, device_t dev return (0); } +/* Pass request for device power state up to parent bridge. */ +int +pcib_power_for_sleep(device_t pcib, device_t dev, int *pstate) +{ + device_t bus; + + bus = device_get_parent(pcib); + return (PCIB_POWER_FOR_SLEEP(bus, dev, pstate)); +} + /* * Try to read the bus number of a host-PCI bridge using appropriate config * registers. Modified: head/sys/dev/pci/pci_private.h ============================================================================== --- head/sys/dev/pci/pci_private.h Tue Aug 17 15:07:23 2010 (r211429) +++ head/sys/dev/pci/pci_private.h Tue Aug 17 15:44:52 2010 (r211430) @@ -38,6 +38,8 @@ */ DECLARE_CLASS(pci_driver); +extern int pci_do_power_resume; + void pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size); void pci_add_child(device_t bus, struct pci_devinfo *dinfo); Modified: head/sys/dev/pci/pcib_if.m ============================================================================== --- head/sys/dev/pci/pcib_if.m Tue Aug 17 15:07:23 2010 (r211429) +++ head/sys/dev/pci/pcib_if.m Tue Aug 17 15:44:52 2010 (r211430) @@ -144,3 +144,13 @@ METHOD int map_msi { uint64_t *addr; uint32_t *data; }; + +# +# Return the device power state to be used during a system sleep state +# transition such as suspend and resume. +# +METHOD int power_for_sleep { + device_t pcib; + device_t dev; + int *pstate; +};