Date: Wed, 15 Jan 2014 04:25:54 +0000 (UTC) From: Justin Hibbits <jhibbits@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r260668 - in projects/pmac_pmu/sys: dev/pci kern powerpc/ofw powerpc/powermac sys Message-ID: <201401150425.s0F4Ps8m038406@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhibbits Date: Wed Jan 15 04:25:54 2014 New Revision: 260668 URL: http://svnweb.freebsd.org/changeset/base/260668 Log: Various updates that I had made against head: * Add the 'Buffer A with handshake update' #define for PMU, for completeness. * Mark OpenPIC as BUS_PASS_INTERRUPT, so it's suspended later and resumed earlier. * Add two new bus methods: bus_suspend_child()/bus_resume_child(), and use those in the bus_generic_suspend()/bus_generic_resume() implementation. * This, in turn, allows us to move all bus recursion logic into the generic functions, allowing the drivers to suspend/resume _only_ themselves. * Make use of these in the PCI driver. Modified: projects/pmac_pmu/sys/dev/pci/pci.c projects/pmac_pmu/sys/dev/pci/pci_private.h projects/pmac_pmu/sys/kern/bus_if.m projects/pmac_pmu/sys/kern/subr_bus.c projects/pmac_pmu/sys/powerpc/ofw/openpic_ofw.c projects/pmac_pmu/sys/powerpc/powermac/maciovar.h projects/pmac_pmu/sys/powerpc/powermac/pmu.c projects/pmac_pmu/sys/powerpc/powermac/viareg.h projects/pmac_pmu/sys/sys/bus.h Modified: projects/pmac_pmu/sys/dev/pci/pci.c ============================================================================== --- projects/pmac_pmu/sys/dev/pci/pci.c Wed Jan 15 04:16:45 2014 (r260667) +++ projects/pmac_pmu/sys/dev/pci/pci.c Wed Jan 15 04:25:54 2014 (r260668) @@ -127,8 +127,6 @@ static device_method_t pci_methods[] = { DEVMETHOD(device_attach, pci_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, pci_suspend), - DEVMETHOD(device_resume, pci_resume), /* Bus interface */ DEVMETHOD(bus_print_child, pci_print_child), @@ -138,6 +136,8 @@ static device_method_t pci_methods[] = { DEVMETHOD(bus_driver_added, pci_driver_added), DEVMETHOD(bus_setup_intr, pci_setup_intr), DEVMETHOD(bus_teardown_intr, pci_teardown_intr), + DEVMETHOD(bus_suspend_child, pci_suspend_child), + DEVMETHOD(bus_resume_child, pci_resume_child), DEVMETHOD(bus_get_dma_tag, pci_get_dma_tag), DEVMETHOD(bus_get_resource_list,pci_get_resource_list), @@ -3364,12 +3364,11 @@ pci_attach(device_t dev) } static void -pci_set_power_children(device_t dev, device_t *devlist, int numdevs, - int state) +pci_set_power_child(device_t dev, device_t child, int state) { - device_t child, pcib; + device_t pcib; struct pci_devinfo *dinfo; - int dstate, i; + int dstate; /* * Set the device to the given state. If the firmware suggests @@ -3379,101 +3378,46 @@ pci_set_power_children(device_t dev, dev * are handled separately. */ pcib = device_get_parent(dev); - for (i = 0; i < numdevs; i++) { - child = devlist[i]; - dinfo = device_get_ivars(child); - dstate = state; - if (device_is_attached(child) && - PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0) - pci_set_powerstate(child, dstate); - } + dinfo = device_get_ivars(child); + dstate = state; + if (device_is_attached(child) && + PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0) + pci_set_powerstate(child, dstate); } int -pci_suspend(device_t dev) +pci_suspend_child(device_t dev, device_t child) { - device_t child, *devlist; struct pci_devinfo *dinfo; - int error, i, numdevs; + int error; - /* - * Save the PCI configuration space for each child and set the - * device in the appropriate power state for this sleep state. - */ - if ((error = device_get_children(dev, &devlist, &numdevs)) != 0) - return (error); - for (i = 0; i < numdevs; i++) { - child = devlist[i]; - dinfo = device_get_ivars(child); - pci_cfg_save(child, dinfo, 0); - } + dinfo = device_get_ivars(child); + pci_cfg_save(child, dinfo, 0); + + error = DEVICE_SUSPEND(child); - /* Suspend devices before potentially powering them down. */ - error = bus_generic_suspend(dev); - if (error) { - free(devlist, M_TEMP); + if (error) return (error); - } + if (pci_do_power_suspend) - pci_set_power_children(dev, devlist, numdevs, - PCI_POWERSTATE_D3); - free(devlist, M_TEMP); + pci_set_power_child(dev, child, PCI_POWERSTATE_D3); + return (0); } int -pci_resume(device_t dev) +pci_resume_child(device_t dev, device_t child) { - device_t child, *devlist; struct pci_devinfo *dinfo; - int error, i, numdevs; + int error; - /* - * Set each child to D0 and restore its PCI configuration space. - */ - if ((error = device_get_children(dev, &devlist, &numdevs)) != 0) - return (error); if (pci_do_power_resume) - pci_set_power_children(dev, devlist, numdevs, - PCI_POWERSTATE_D0); - - /* Now the device is powered up, restore its config space. */ - for (i = 0; i < numdevs; i++) { - child = devlist[i]; - dinfo = device_get_ivars(child); + pci_set_power_child(dev, child, PCI_POWERSTATE_D0); + error = DEVICE_RESUME(child); - pci_cfg_restore(child, dinfo); - if (!device_is_attached(child)) - pci_cfg_save(child, dinfo, 1); - } + dinfo = device_get_ivars(child); + pci_cfg_restore(child, dinfo); - /* - * Resume critical devices first, then everything else later. - */ - for (i = 0; i < numdevs; i++) { - child = devlist[i]; - switch (pci_get_class(child)) { - case PCIC_DISPLAY: - case PCIC_MEMORY: - case PCIC_BRIDGE: - case PCIC_BASEPERIPH: - error = DEVICE_RESUME(child); - break; - } - } - for (i = 0; i < numdevs; i++) { - child = devlist[i]; - switch (pci_get_class(child)) { - case PCIC_DISPLAY: - case PCIC_MEMORY: - case PCIC_BRIDGE: - case PCIC_BASEPERIPH: - break; - default: - error = DEVICE_RESUME(child); - } - } - free(devlist, M_TEMP); return (error); } Modified: projects/pmac_pmu/sys/dev/pci/pci_private.h ============================================================================== --- projects/pmac_pmu/sys/dev/pci/pci_private.h Wed Jan 15 04:16:45 2014 (r260667) +++ projects/pmac_pmu/sys/dev/pci/pci_private.h Wed Jan 15 04:25:54 2014 (r260668) @@ -114,8 +114,8 @@ int pci_child_location_str_method(devic int pci_child_pnpinfo_str_method(device_t cbdev, device_t child, char *buf, size_t buflen); int pci_assign_interrupt_method(device_t dev, device_t child); -int pci_resume(device_t dev); -int pci_suspend(device_t dev); +int pci_resume_child(device_t dev, device_t child); +int pci_suspend_child(device_t dev, device_t child); bus_dma_tag_t pci_get_dma_tag(device_t bus, device_t dev); /** Restore the config register state. The state must be previously Modified: projects/pmac_pmu/sys/kern/bus_if.m ============================================================================== --- projects/pmac_pmu/sys/kern/bus_if.m Wed Jan 15 04:16:45 2014 (r260667) +++ projects/pmac_pmu/sys/kern/bus_if.m Wed Jan 15 04:25:54 2014 (r260668) @@ -670,3 +670,25 @@ METHOD int remap_intr { device_t _child; u_int _irq; } DEFAULT null_remap_intr; + +/** + * @brief Resume a child of the bus + * + * @param _dev the bus device + * @param _child the child device + */ +METHOD int resume_child { + device_t _dev; + device_t _child; +} DEFAULT bus_generic_resume_child; + +/** + * @brief Suspend a child of the bus + * + * @param _dev the bus device + * @param _child the child device + */ +METHOD int suspend_child { + device_t _dev; + device_t _child; +} DEFAULT bus_generic_suspend_child; Modified: projects/pmac_pmu/sys/kern/subr_bus.c ============================================================================== --- projects/pmac_pmu/sys/kern/subr_bus.c Wed Jan 15 04:16:45 2014 (r260667) +++ projects/pmac_pmu/sys/kern/subr_bus.c Wed Jan 15 04:25:54 2014 (r260668) @@ -91,7 +91,6 @@ struct devclass { device_t *devices; /* array of devices indexed by unit */ int maxunit; /* size of devices array */ int flags; - int pass; #define DC_HAS_CHILDREN 1 struct sysctl_ctx_list sysctl_ctx; @@ -125,6 +124,7 @@ struct device { char* nameunit; /**< name+unit e.g. foodev0 */ char* desc; /**< driver specific description */ int busy; /**< count of calls to device_busy() */ + int pass; /**< pass number this device was attached at */ device_state_t state; /**< current device state */ uint32_t devflags; /**< api level flags for device_get_flags() */ u_int flags; /**< internal device flags */ @@ -136,7 +136,6 @@ struct device { #define DF_DONENOMATCH 0x20 /* don't execute DEVICE_NOMATCH again */ #define DF_EXTERNALSOFTC 0x40 /* softc not allocated by us */ #define DF_REBID 0x80 /* Can rebid after attach */ -#define DF_SUSPENDED 0x100 /* Device is suspended. */ u_int order; /**< order from device_add_child_ordered() */ void *ivars; /**< instance variables */ void *softc; /**< current driver's variables */ @@ -1086,7 +1085,6 @@ devclass_add_driver(devclass_t dc, drive TAILQ_INSERT_TAIL(&dc->drivers, dl, link); driver->refs++; /* XXX: kobj_mtx */ dl->pass = pass; - (*dcp)->pass = pass; /* Used in suspend/resume. */ driver_register_pass(dl); devclass_driver_added(dc, driver); @@ -2815,6 +2813,7 @@ device_attach(device_t dev) else dev->state = DS_ATTACHED; dev->flags &= ~DF_DONENOMATCH; + dev->pass = bus_current_pass; devadded(dev); return (0); } @@ -3587,6 +3586,38 @@ bus_generic_shutdown(device_t dev) } /** + * @brief Helper function for implementing DEVICE_SUSPEND_CHILD() + * + * This function can be used to help implement the DEVICE_SUSPEND_CHILD() + * for a bus. It calls DEVICE_SUSPEND() for the given child. + */ +int +bus_generic_suspend_child(device_t dev, device_t child) +{ + int error; + + error = DEVICE_SUSPEND(child); + + return (error); +} + +/** + * @brief Helper function for implementing DEVICE_RESUME_CHILD() + * + * This function can be used to help implement the DEVICE_RESUME_CHILD() + * for a bus. It calls DEVICE_RESUME() for the given child. + */ +int +bus_generic_resume_child(device_t dev, device_t child) +{ + int error; + + error = DEVICE_RESUME(child); + + return (error); +} + +/** * @brief Helper function for implementing DEVICE_SUSPEND() * * This function can be used to help implement the DEVICE_SUSPEND() @@ -3598,30 +3629,41 @@ bus_generic_shutdown(device_t dev) int bus_generic_suspend(device_t dev) { - int error; - int again = 0; + int error = 0; device_t child, child2; + if (dev->state == DS_SUSPENDED) + return (0); + TAILQ_FOREACH(child, &dev->children, link) { - if (!(child->flags & DF_SUSPENDED)) { - error = DEVICE_SUSPEND(child); - if (error && error != EAGAIN) { - for (child2 = TAILQ_FIRST(&dev->children); - child2 && child2 != child; - child2 = TAILQ_NEXT(child2, link)) { - DEVICE_RESUME(child2); - child2->flags &= ~DF_SUSPENDED; - } - return (error); + if (child->state != DS_SUSPENDED) + error = bus_generic_suspend(child); + if (error == 0) { + /* We won't busy ourselves with busy devices. */ + if (child->state == DS_BUSY) + error = (EBUSY); + else if (child->pass >= bus_current_pass && child->state == DS_ATTACHED) { + printf("Suspending %s, child of %s\n", child->nameunit, dev->nameunit); + error = BUS_SUSPEND_CHILD(dev, child); + if (error != 0) + printf("Error suspending child %s: %d\n", child->nameunit, error); + if (error == 0) + child->state = DS_SUSPENDED; } - if (error == EAGAIN) { - again = EAGAIN; - continue; + } + + if (error) { + for (child2 = TAILQ_FIRST(&dev->children); + child2 && child2 != child; + child2 = TAILQ_NEXT(child2, link)) { + BUS_RESUME_CHILD(dev, child2); + bus_generic_resume(child2); } - child->flags |= DF_SUSPENDED; + return (error); } } - return (again); + + return (error); } /** @@ -3634,31 +3676,23 @@ int bus_generic_resume(device_t dev) { device_t child; - int error = 0; TAILQ_FOREACH(child, &dev->children, link) { - if (child->flags & DF_SUSPENDED) { - if (child->devclass->pass > bus_current_pass) { - if (bootverbose) - printf("Skipping: %s: %d, %d\n", - child->nameunit, - child->devclass->pass, - bus_current_pass); - error = EAGAIN; - continue; - } - if (DEVICE_RESUME(child) == EAGAIN) { - error = EAGAIN; - continue; - } + if (child->pass == bus_current_pass && child->state == DS_SUSPENDED) { + printf("Resuming %s, child of %s\n", child->nameunit, dev->nameunit); + BUS_RESUME_CHILD(dev, child); + /* if resume fails, there's nothing we can usefully do... */ - child->flags &= ~DF_SUSPENDED; + /* Re-mark the child as attached. */ + child->state = DS_ATTACHED; + } + + /* Recurse through the child, resuming all its children. */ + if (child->pass <= bus_current_pass) { + bus_generic_resume(child); } - else - if (bootverbose) - printf("Skipping %s: already resumed\n", child->nameunit); } - return (error); + return (0); } /** @@ -4465,18 +4499,22 @@ root_resume(device_t dev) { struct driverlink *dl; int error = 0; + int rv = 0; TAILQ_FOREACH(dl, &passes, passlink) { + /* + * Raise the pass level to the next level and rescan + * the tree. + */ bus_current_pass = dl->pass; error = bus_generic_resume(dev); - - if (error != EAGAIN) - break; + if (error != 0) + rv = error; } - if (error == 0) + if (rv == 0) devctl_notify("kern", "power", "resume", NULL); - return (error); + return (rv); } static int @@ -4487,11 +4525,25 @@ root_suspend(device_t dev) TAILQ_FOREACH_REVERSE(dl, &passes, driver_list, passlink) { bus_current_pass = dl->pass; + printf("New pass: %d\n", bus_current_pass); error = bus_generic_suspend(dev); - if (error != EAGAIN) + if (error != 0) break; } + if (error != 0) { + printf("Error %d\n", error); + TAILQ_FOREACH_FROM(dl, &passes, passlink) { + if (dl->pass <= bus_current_pass) + continue; + + bus_current_pass = dl->pass; + error = bus_generic_resume(dev); + if (error != 0) + break; + } + } + return (error); } Modified: projects/pmac_pmu/sys/powerpc/ofw/openpic_ofw.c ============================================================================== --- projects/pmac_pmu/sys/powerpc/ofw/openpic_ofw.c Wed Jan 15 04:16:45 2014 (r260667) +++ projects/pmac_pmu/sys/powerpc/ofw/openpic_ofw.c Wed Jan 15 04:25:54 2014 (r260668) @@ -95,7 +95,7 @@ static driver_t openpic_ofw_driver = { DRIVER_MODULE(openpic, nexus, openpic_ofw_driver, openpic_devclass, 0, 0); DRIVER_MODULE(openpic, simplebus, openpic_ofw_driver, openpic_devclass, 0, 0); -DRIVER_MODULE(openpic, macio, openpic_ofw_driver, openpic_devclass, 0, 0); +EARLY_DRIVER_MODULE(openpic, macio, openpic_ofw_driver, openpic_devclass, 0, 0, BUS_PASS_INTERRUPT); static int openpic_ofw_probe(device_t dev) Modified: projects/pmac_pmu/sys/powerpc/powermac/maciovar.h ============================================================================== --- projects/pmac_pmu/sys/powerpc/powermac/maciovar.h Wed Jan 15 04:16:45 2014 (r260667) +++ projects/pmac_pmu/sys/powerpc/powermac/maciovar.h Wed Jan 15 04:25:54 2014 (r260668) @@ -48,6 +48,12 @@ #define KEYLARGO_FCR4 0x48 #define KEYLARGO_FCR5 0x4c +#define K2_FCR10 0x24 +#define K2_FCR9 0x28 +#define K2_FCR8 0x2c +#define K2_FCR7 0x30 +#define K2_FCR6 0x34 + #define FCR_ENET_ENABLE 0x60000000 #define FCR_ENET_RESET 0x80000000 @@ -112,6 +118,230 @@ #define FCR3_I2S0_CLK18_ENABLE 0x00004000 #define FCR3_VIA_CLK16_ENABLE 0x00008000 +#define KEYLARGO_MEDIABAY 0x34 +#define KEYLARGO_MB0_DEV_ENABLE 0x00001000 +#define KEYLARGO_MB0_DEV_POWER 0x00000400 +#define KEYLARGO_MB0_DEV_RESET 0x00000200 +#define KEYLARGO_MB0_ENABLE 0x00000100 +#define KEYLARGO_MB1_DEV_ENABLE 0x10000000 +#define KEYLARGO_MB1_DEV_POWER 0x04000000 +#define KEYLARGO_MB1_DEV_RESET 0x02000000 +#define KEYLARGO_MB1_ENABLE 0x01000000 + +#define FCR0_CHOOSE_SCCB 0x00000001 +#define FCR0_CHOOSE_SCCA 0x00000002 +#define FCR0_SLOW_SCC_PCLK 0x00000004 +#define FCR0_RESET_SCC 0x00000008 +#define FCR0_SCCA_ENABLE 0x00000010 +#define FCR0_SCCB_ENABLE 0x00000020 +#define FCR0_SCC_CELL_ENABLE 0x00000040 +#define FCR0_CHOOSE_VIA 0x00000080 +#define FCR0_HIGH_BAND_FOR_1MB 0x00000080 +#define FCR0_USE_IR_SOURCE_2 0x00000200 /* KeyLargo */ +#define FCR0_USE_IR_SOURCE_1 0x00000400 /* KeyLargo */ +#define FCR0_USB0_PMI_ENABLE 0x00000400 /* Pangea and Intrepid */ +#define FCR0_IRDA_SWRESET 0x00000800 /* KeyLargo */ +#define FCR0_USB0_REF_SUSPEND_SEL 0x00000800 /* Pangea and Intrepid */ +#define FCR0_IRDA_DEFAULT1 0x00001000 /* KeyLargo */ +#define FCR0_USB0_REF_SUSPEND 0x00001000 /* Pangea and Intrepid */ +#define FCR0_IRDA_DEFAULT0 0x00002000 /* KeyLargo */ +#define FCR0_USB0_PAD_SUSPEND_SEL 0x00002000 /* Pangea and Intrepid */ +#define FCR0_IRDA_FAST_CON 0x00004000 /* KeyLargo */ +#define FCR0_USB1_PMI_ENABLE 0x00004000 /* Pangea and Intrepid */ +#define FCR0_IRDA_ENABLE 0x00008000 +#define FCR0_USB1_REF_SUSPEND_SEL 0x00008000 +#define FCR0_IRDA_CLK32_ENABLE 0x00010000 +#define FCR0_USB1_REF_SUSPEND 0x00010000 +#define FCR0_IRDA_CLK19_ENABLE 0x00020000 +#define FCR0_USB1_PAD_SUSPEND_SEL 0x00020000 +#define FCR0_USB0_PAD_SUSPEND_0 0x00040000 +#define FCR0_USB0_PAD_SUSPEND_1 0x00080000 +#define FCR0_USB0_CELL_ENABLE 0x00100000 +#define FCR0_USB1_PAD_SUSPEND_0 0x00400000 +#define FCR0_USB1_PAD_SUSPEND_1 0x00800000 +#define FCR0_USB1_CELL_ENABLE 0x01000000 +#define FCR0_USB_REF_SUSPEND 0x10000000 + +#define FCR1_USB2_PMI_ENABLE 0x00000001 +#define FCR1_AUDIO_SEL_22MCLK 0x00000002 +#define FCR1_USB2_REF_SUSPEND_SEL 0x00000002 +#define FCR1_USB2_REF_SUSPEND 0x00000002 +#define FCR1_AUDIO_CLK_ENABLE 0x00000008 +#define FCR1_USB2_PAD_SUSPEND_SEL 0x00000008 +#define FCR1_USB2_PAD_SUSPEND0 0x00000010 +#define FCR1_AUDIO_CLKOUT_ENABLE 0x00000020 +#define FCR1_USB2_PAD_SUSPEND1 0x00000020 +#define FCR1_AUDIO_CELL_ENABLE 0x00000040 +#define FCR1_USB2_CELL_ENABLE 0x00000040 +#define FCR1_CHOOSE_AUDIO 0x00000080 +#define FCR1_CHOOSE_I2S0 0x00000400 +#define FCR1_I2S0_CELL_ENABLE 0x00000400 +#define FCR1_I2S0_CLK_ENABLE 0x00001000 +#define FCR1_I2S0_ENABLE 0x00002000 +#define FCR1_I2S1_CELL_ENABLE 0x00020000 +#define FCR1_I2S1_CLK_ENABLE 0x00080000 +#define FCR1_I2S1_ENABLE 0x00100000 +#define FCR1_EIDE0_ENABLE 0x00800000 +#define FCR1_EIDE0_RESET 0x01000000 +#define FCR1_EIDE1_ENABLE 0x04000000 +#define FCR1_EIDE1_RESET 0x08000000 +#define FCR1_UIDE_ENABLE 0x20000000 +#define FCR1_UIDE_RESET 0x40000000 + +#define FCR2_IOBUS_ENABLE 0x00000002 +#define FCR2_SLEEP_STATE 0x00000100 +#define FCR2_STOP_ALL_KL_CLOCKS 0x00000100 +#define FCR2_MPIC_ENABLE 0x00020000 +#define FCR2_CARD_SLOT_RESET 0x00040000 +#define FCR2_ALT_DATA_OUT 0x02000000 + +#define FCR3_SHUTDOWN_PLL_TOTAL 0x00000001 +#define FCR3_SHUTDOWN_PLL_KW6 0x00000002 +#define FCR3_SHUTDOWN_PLL3 0x00000002 +#define FCR3_SHUTDOWN_PLL_KW4 0x00000004 +#define FCR3_SHUTDOWN_PLL2 0x00000004 +#define FCR3_SHUTDOWN_PLL_KW35 0x00000008 +#define FCR3_SHUTDOWN_PLL1 0x00000008 +#define FCR3_SHUTDOWN_PLL_KW12 0x00000010 +#define FCR3_ENABLE_PLL3_SHUTDOWN 0x00000010 +#define FCR3_ENABLE_PLL2_SHUTDOWN 0x00000020 +#define FCR3_ENABLE_PLL1_SHUTDOWN 0x00000040 +#define FCR3_SHUTDOWN_PLL_2X 0x00000080 +#define FCR3_CLK_66_ENABLE 0x00000100 +#define FCR3_CLK_49_ENABLE 0x00000200 +#define FCR3_CLK_45_ENABLE 0x00000400 +#define FCR3_CLK_31_ENABLE 0x00000800 +#define FCR3_TMR_CLK18_ENABLE 0x00001000 +#define FCR3_I2S1_CLK18_ENABLE 0x00002000 +#define FCR3_I2S0_CLK18_ENABLE 0x00004000 +#define FCR3_VIA_CLK16_ENABLE 0x00008000 +#define FCR3_VIA_CLK32_ENABLE 0x00008000 +#define FCR3_PORT5_DISCONNECT_SELECT 0x00010000 +#define FCR3_PORT5_CONNECT_SELECT 0x00020000 +#define FCR3_PORT5_RESUME_SELECT 0x00040000 +#define FCR3_PORT5_ENABLE 0x00080000 +#define FCR3_STOPPING_33_ENABLED 0x00080000 +#define FCR3_PLL_ENABLE_TEST 0x00080000 +#define FCR3_PORT5_DISCONNECT 0x00100000 +#define FCR3_PORT5_CONNECT 0x00200000 +#define FCR3_PORT5_RESUME 0x00400000 +#define FCR3_PORT6_DISCONNECT_SELECT 0x00800000 +#define FCR3_PORT6_CONNECT_SELECT 0x02000000 +#define FCR3_PORT6_RESUME_SELECT 0x04000000 +#define FCR3_PORT6_ENABLE 0x08000000 +#define FCR3_PORT6_DISCONNECT 0x10000000 +#define FCR3_PORT6_CONNECT 0x20000000 +#define FCR3_PORT6_RESUME 0x40000000 + +#define FCR4_PORT1_DISCONNECT_SELECT 0x00000001 +#define FCR4_PORT1_CONNECT_SELECT 0x00000002 +#define FCR4_PORT1_RESUME_SELECT 0x00000004 +#define FCR4_PORT1_ENABLE 0x00000008 +#define FCR4_PORT1_DISCONNECT 0x00000010 +#define FCR4_PORT1_CONNECT 0x00000020 +#define FCR4_PORT1_RESUME 0x00000040 +#define FCR4_PORT2_DISCONNECT_SELECT 0x00000100 +#define FCR4_PORT2_CONNECT_SELECT 0x00000200 +#define FCR4_PORT2_RESUME_SELECT 0x00000400 +#define FCR4_PORT2_ENABLE 0x00000800 +#define FCR4_PORT2_DISCONNECT 0x00001000 +#define FCR4_PORT2_CONNECT 0x00002000 +#define FCR4_PORT2_RESUME 0x00004000 +#define FCR4_PORT3_DISCONNECT_SELECT 0x00010000 +#define FCR4_PORT3_CONNECT_SELECT 0x00020000 +#define FCR4_PORT3_RESUME_SELECT 0x00040000 +#define FCR4_PORT3_ENABLE 0x00080000 +#define FCR4_PORT3_DISCONNECT 0x00100000 +#define FCR4_PORT3_CONNECT 0x00200000 +#define FCR4_PORT3_RESUME 0x00400000 +#define FCR4_PORT4_DISCONNECT_SELECT 0x01000000 +#define FCR4_PORT4_CONNECT_SELECT 0x02000000 +#define FCR4_PORT4_RESUME_SELECT 0x04000000 +#define FCR4_PORT4_ENABLE 0x08000000 +#define FCR4_PORT4_DISCONNECT 0x10000000 +#define FCR4_PORT4_CONNECT 0x20000000 +#define FCR4_PORT4_RESUME 0x40000000 + +#define FCR5_VIA_USE_CLK31 0x00000001 +#define FCR5_SCC_USE_CLK31 0x00000002 +#define FCR5_PWM_CLK32_ENABLE 0x00000004 +#define FCR5_CLK3_68_ENABLE 0x00000010 +#define FCR5_CLK32_ENABLE 0x00000020 + +/* + * K2 FCRs. + */ +#define FCR0_K2_USB0_SWRESET 0x00200000 +#define FCR0_K2_USB1_SWRESET 0x02000000 +#define FCR0_K2_RING_PME_DISABLE 0x08000000 + +#define FCR1_K2_I2S2_CELL_ENABLE 0x00000010 +#define FCR1_K2_I2S2_CLK_ENABLE 0x00000040 +#define FCR1_K2_I2S2_ENABLE 0x00000080 +#define FCR1_K2_PCI1_BUS_RESET 0x00000100 +#define FCR1_K2_PCI1_SLEEP_RESET_EN 0x00000200 +#define FCR1_K2_PCI1_CLK_ENABLE 0x00004000 +#define FCR1_K2_FW_CLK_ENABLE 0x00008000 +#define FCR1_K2_FW_RESET 0x00010000 +#define FCR1_K2_I2S1_SWRESET 0x00040000 +#define FCR1_K2_GB_CLK_ENABLE 0x00400000 +#define FCR1_GB_PWR_DOWN 0x00800000 +#define FCR1_K2_GB_RESET 0x01000000 +#define FCR1_K2_SATA_CLK_ENABLE 0x02000000 +#define FCR1_K2_SATA_PWR_DOWN 0x04000000 +#define FCR1_K2_SATA_RESET 0x08000000 +#define FCR1_K2_UATA_CLK_ENABLE 0x10000000 +#define FCR1_K2_UATA_RESET 0x40000000 +#define FCR1_K2_UATA_CHOOSE_CLK66 0x80000000 + +#define FCR2_K2_PWM0_AUTO_STOP_EN 0x00000010 +#define FCR2_K2_PWM1_AUTO_STOP_EN 0x00000020 +#define FCR2_K2_PWM2_AUTO_STOP_EN 0x00000040 +#define FCR2_K2_PWM3_AUTO_STOP_EN 0x00000080 +#define FCR2_K2_PWM0_OVER_TEMP_EN 0x00000100 +#define FCR2_K2_PWM1_OVER_TEMP_EN 0x00000200 +#define FCR2_K2_PWM2_OVER_TEMP_EN 0x00000400 +#define FCR2_K2_PWM3_OVER_TEMP_EN 0x00000800 +#define FCR2_K2_HT_ENABLE_INTERRUPTS 0x00008000 +#define FCR2_K2_SB_MPIC_ENABLE_OUTPUTS 0x00010000 +#define FCR2_K2_SB_MPIC_RESET 0x00010000 +#define FCR2_K2_FW_LINK_ON_INT_EN 0x00040000 +#define FCR2_K2_FW_ALT_LINK_ON_SEL 0x00080000 +#define FCR2_K2_PWMS_EN 0x00100000 +#define FCR2_K2_GB_WAKE_INT_EN 0x00200000 +#define FCR2_K2_GB_ENERGY_INT_EN 0x00400000 +#define FCR2_K2_BLOCK_EXT_GPIO1 0x00800000 +#define FCR2_K2_PCI0_BRIDGE_INT 0x01000000 +#define FCR2_K2_PCI1_BRIDGE_INT 0x02000000 +#define FCR2_K2_PCI2_BRIDGE_INT 0x04000000 +#define FCR2_K2_PCI3_BRIDGE_INT 0x08000000 +#define FCR2_K2_PCI4_BRIDGE_INT 0x10000000 +#define FCR2_K2_HT_NONFATAL_ERROR 0x40000000 +#define FCR2_K2_HT_FATAL_ERROR 0x80000000 + +#define FCR3_K2_ENABLE_OSC25_SHUTDOWN 0x00000001 +#define FCR3_K2_ENABLE_FW_PAD_PWRDOWN 0x00000002 +#define FCR3_K2_ENABLE_GBPAD_PWRDOWN 0x00000004 +#define FCR3_K2_ENABLE_PLL0_SHUTDOWN 0x00000080 +#define FCR3_K2_ENABLE_PLL6_SHUTDOWN 0x00000100 +#define FCR3_K2_DYN_CLK_STOP_ENABLE 0x00000800 +#define FCR3_K2_I2S2_CLK18_ENABLE 0x00008000 + +#define FCR9_K2_PCI1_CLK66_IS_STOPPED 0x00000001 +#define FCR9_K2_PCI2_CLK66_IS_STOPPED 0x00000002 +#define FCR9_K2_FW_CLK66_IS_STOPPED 0x00000004 +#define FCR9_K2_UATA_CLK66_IS_STOPPED 0x00000008 +#define FCR9_K2_UATA_CLK100_IS_STOPPED 0x00000010 +#define FCR9_K2_PCI3_CLK66_IS_STOPPED 0x00000020 +#define FCR9_K2_GB_CLK66_IS_STOPPED 0x00000040 +#define FCR9_K2_PCI4_CLK66_IS_STOPPED 0x00000080 +#define FCR9_K2_SATA_CLK66_IS_STOPPED 0x00000100 +#define FCR9_K2_USB0_CLK48_IS_STOPPED 0x00000200 +#define FCR9_K2_USB1_CLK48_IS_STOPPED 0x00000400 +#define FCR9_K2_CLK45_IS_STOPPED 0x00000800 +#define FCR9_K2_CLK49_IS_STOPPED 0x00001000 +#define FCR9_K2_OSC25_SHUTDOWN 0x00008000 + /* * Format of a macio reg property entry. */ Modified: projects/pmac_pmu/sys/powerpc/powermac/pmu.c ============================================================================== --- projects/pmac_pmu/sys/powerpc/powermac/pmu.c Wed Jan 15 04:16:45 2014 (r260667) +++ projects/pmac_pmu/sys/powerpc/powermac/pmu.c Wed Jan 15 04:25:54 2014 (r260668) @@ -132,10 +132,10 @@ static device_method_t pmu_methods[] = /* Device interface */ DEVMETHOD(device_probe, pmu_probe), DEVMETHOD(device_attach, pmu_attach), - DEVMETHOD(device_detach, pmu_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, pmu_suspend), - DEVMETHOD(device_resume, pmu_resume), + DEVMETHOD(device_detach, pmu_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, pmu_suspend), + DEVMETHOD(device_resume, pmu_resume), /* ADB bus interface */ DEVMETHOD(adb_hb_send_raw_packet, pmu_adb_send), @@ -157,7 +157,7 @@ static driver_t pmu_driver = { static devclass_t pmu_devclass; -DRIVER_MODULE(pmu, macio, pmu_driver, pmu_devclass, 0, 0); +EARLY_DRIVER_MODULE(pmu, macio, pmu_driver, pmu_devclass, 0, 0, BUS_PASS_RESOURCE); DRIVER_MODULE(adb, pmu, adb_driver, adb_devclass, 0, 0); static int pmuextint_probe(device_t); @@ -431,6 +431,10 @@ pmu_attach(device_t dev) "sleep", CTLTYPE_INT | CTLFLAG_RW, sc, 0, pmu_sleep, "I", "Put the machine to sleep"); + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "sleep", CTLTYPE_INT | CTLFLAG_RW, sc, 0, + pmu_sleep, "I", "Put the machine to sleep"); + if (sc->sc_batteries > 0) { struct sysctl_oid *oid, *battroot; char battnum[2]; @@ -540,43 +544,6 @@ pmu_write_reg(struct pmu_softc *sc, u_in bus_write_1(sc->sc_memr, offset, value); } -static void -pmu_save_state(struct pmu_softc *sc) -{ - sc->saved_regs[0] = pmu_read_reg(sc, vBufA); - sc->saved_regs[1] = pmu_read_reg(sc, vDirA); - sc->saved_regs[2] = pmu_read_reg(sc, vBufB); - sc->saved_regs[3] = pmu_read_reg(sc, vDirB); - sc->saved_regs[4] = pmu_read_reg(sc, vPCR); - sc->saved_regs[5] = pmu_read_reg(sc, vACR); - sc->saved_regs[6] = pmu_read_reg(sc, vIER); - sc->saved_regs[7] = pmu_read_reg(sc, vT1C); - sc->saved_regs[8] = pmu_read_reg(sc, vT1CH); -} - -static void -pmu_restore_state(struct pmu_softc *sc) -{ - pmu_write_reg(sc, vBufA, sc->saved_regs[0]); - eieio(); - pmu_write_reg(sc, vDirA, sc->saved_regs[1]); - eieio(); - pmu_write_reg(sc, vBufB, sc->saved_regs[2]); - eieio(); - pmu_write_reg(sc, vDirB, sc->saved_regs[3]); - eieio(); - pmu_write_reg(sc, vPCR, sc->saved_regs[4]); - eieio(); - pmu_write_reg(sc, vACR, sc->saved_regs[5]); - eieio(); - pmu_write_reg(sc, vIER, sc->saved_regs[6]); - eieio(); - pmu_write_reg(sc, vT1C, sc->saved_regs[7]); - eieio(); - pmu_write_reg(sc, vT1CH, sc->saved_regs[8]); - eieio(); -} - static int pmu_send_byte(struct pmu_softc *sc, uint8_t data) { @@ -1079,6 +1046,34 @@ pmu_settime(device_t dev, struct timespe return (0); } + +static void +pmu_save_state(struct pmu_softc *sc) +{ + sc->saved_regs[0] = pmu_read_reg(sc, vBufA); + sc->saved_regs[1] = pmu_read_reg(sc, vDirA); + sc->saved_regs[2] = pmu_read_reg(sc, vBufB); + sc->saved_regs[3] = pmu_read_reg(sc, vDirB); + sc->saved_regs[4] = pmu_read_reg(sc, vPCR); + sc->saved_regs[5] = pmu_read_reg(sc, vACR); + sc->saved_regs[6] = pmu_read_reg(sc, vIER); + sc->saved_regs[7] = pmu_read_reg(sc, vT1C); + sc->saved_regs[8] = pmu_read_reg(sc, vT1CH); +} + +static void +pmu_restore_state(struct pmu_softc *sc) +{ + pmu_write_reg(sc, vBufA, sc->saved_regs[0]); + pmu_write_reg(sc, vDirA, sc->saved_regs[1]); + pmu_write_reg(sc, vBufB, sc->saved_regs[2]); + pmu_write_reg(sc, vDirB, sc->saved_regs[3]); + pmu_write_reg(sc, vPCR, sc->saved_regs[4]); + pmu_write_reg(sc, vACR, sc->saved_regs[5]); + pmu_write_reg(sc, vIER, sc->saved_regs[6]); + pmu_write_reg(sc, vT1C, sc->saved_regs[7]); + pmu_write_reg(sc, vT1CH, sc->saved_regs[8]); +} static int pmu_suspend(device_t dev) @@ -1189,31 +1184,6 @@ void pmu_sleep_int(void) powerpc_sync(); } -static int -pmu_sleep(SYSCTL_HANDLER_ARGS) -{ - u_int sleep = 0; - int error; - - error = sysctl_handle_int(oidp, &sleep, 0, req); - - if (error || !req->newptr) - return (error); - - mtx_lock(&Giant); - error = DEVICE_SUSPEND(root_bus); - if (error == 0) { - spinlock_enter(); - pmu_sleep_int(); - - spinlock_exit(); - DEVICE_RESUME(root_bus); - } - mtx_unlock(&Giant); - - return (error); -} - int pmu_set_speed(int low_speed) { @@ -1240,3 +1210,29 @@ pmu_set_speed(int low_speed) return (0); } + +static int +pmu_sleep(SYSCTL_HANDLER_ARGS) +{ + u_int sleep = 0; + int error; + + error = sysctl_handle_int(oidp, &sleep, 0, req); + + if (error || !req->newptr) + return (error); + + mtx_lock(&Giant); + error = DEVICE_SUSPEND(root_bus); + if (error == 0) { + spinlock_enter(); + pmu_sleep_int(); + + spinlock_exit(); + DEVICE_RESUME(root_bus); + } + mtx_unlock(&Giant); + printf("Fully resumed.\n"); + + return (error); +} Modified: projects/pmac_pmu/sys/powerpc/powermac/viareg.h ============================================================================== --- projects/pmac_pmu/sys/powerpc/powermac/viareg.h Wed Jan 15 04:16:45 2014 (r260667) +++ projects/pmac_pmu/sys/powerpc/powermac/viareg.h Wed Jan 15 04:25:54 2014 (r260668) @@ -30,6 +30,7 @@ /* VIA interface registers */ #define vBufB 0x0000 /* register B */ +#define vBufAH 0x0200 /* register A (handshake) */ #define vDirB 0x0400 /* data direction register */ #define vDirA 0x0600 /* data direction register */ #define vT1C 0x0800 /* Timer 1 counter Lo */ Modified: projects/pmac_pmu/sys/sys/bus.h ============================================================================== --- projects/pmac_pmu/sys/sys/bus.h Wed Jan 15 04:16:45 2014 (r260667) +++ projects/pmac_pmu/sys/sys/bus.h Wed Jan 15 04:25:54 2014 (r260668) @@ -54,7 +54,8 @@ typedef enum device_state { DS_ALIVE = 20, /**< @brief probe succeeded */ DS_ATTACHING = 25, /**< @brief currently attaching */ DS_ATTACHED = 30, /**< @brief attach method called */ - DS_BUSY = 40 /**< @brief device is open */ + DS_BUSY = 40, /**< @brief device is open */ + DS_SUSPENDED = 50, /**< @brief device is suspended */ } device_state_t; /** @@ -340,6 +341,7 @@ int bus_generic_read_ivar(device_t dev, int bus_generic_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r); int bus_generic_resume(device_t dev); +int bus_generic_resume_child(device_t dev, device_t child); int bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *intr, @@ -358,6 +360,7 @@ int bus_generic_rl_release_resource (dev int bus_generic_shutdown(device_t dev); int bus_generic_suspend(device_t dev); +int bus_generic_suspend_child(device_t dev, device_t child); int bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie); int bus_generic_write_ivar(device_t dev, device_t child, int which,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401150425.s0F4Ps8m038406>