svn commit: r260668 - in projects/pmac_pmu/sys: dev/pci kern powerpc/ofw powerpc/powermac sys
Justin Hibbits
jhibbits at FreeBSD.org
Wed Jan 15 04:25:56 UTC 2014
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,
More information about the svn-src-projects
mailing list