summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/ppm/ppm_subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/io/ppm/ppm_subr.c')
-rw-r--r--usr/src/uts/common/io/ppm/ppm_subr.c74
1 files changed, 63 insertions, 11 deletions
diff --git a/usr/src/uts/common/io/ppm/ppm_subr.c b/usr/src/uts/common/io/ppm/ppm_subr.c
index 4bcd24c877..617ac3a380 100644
--- a/usr/src/uts/common/io/ppm/ppm_subr.c
+++ b/usr/src/uts/common/io/ppm/ppm_subr.c
@@ -207,6 +207,7 @@ ppm_lookup_hndl(int model, ppm_dc_t *key_dc)
#define PPM_CTRL_PROP_SUFFIX "-control"
struct ppm_domit ppm_domit_data[] = {
+ "SX", PPMD_SX, 0, PPMD_ON,
"CPU", PPMD_CPU, PPMD_LOCK_ALL, PPMD_ON,
"FET", PPMD_FET, PPMD_LOCK_ONE, PPMD_ON,
"PCI", PPMD_PCI, PPMD_LOCK_ONE, PPMD_ON,
@@ -401,11 +402,19 @@ ppm_lookup_dev(dev_info_t *dip)
PPM_GET_PATHNAME(dip, path);
for (domp = ppm_domain_p; domp; domp = domp->next) {
- if (PPM_DOMAIN_UP(domp))
+ if (PPM_DOMAIN_UP(domp)) {
for (dbp = domp->conflist; dbp; dbp = dbp->next) {
+ /*
+ * allow claiming root without knowing
+ * its full name
+ */
+ if (dip == ddi_root_node() &&
+ strcmp(dbp->name, "/") == 0)
+ return (domp);
if (ppm_match_devs(path, dbp) == 0)
return (domp);
}
+ }
}
return (NULL);
@@ -514,7 +523,8 @@ ppm_match_devs(char *dev_path, ppm_db_t *dbp)
/* "<exact match>*" */
if (dbp->name[dbp->wcpos[0] + 1] == 0) {
cp = path + dbp->wcpos[0];
- while (*cp && (*cp++ != '/'));
+ while (*cp && (*cp++ != '/'))
+ ;
return ((*cp == 0) ? 0 : -1);
}
@@ -761,6 +771,22 @@ ppm_init_cb(dev_info_t *dip)
for (domp = ppm_domain_p; domp != NULL; domp = domp->next) {
for (dc = domp->dc; dc; dc = dc->next) {
+ /*
+ * Warning: This code is rather confusing.
+ *
+ * It intends to ensure that ppm_init_lyr() is only
+ * called ONCE for a device that may be associated
+ * with more than one domain control.
+ * So, what it does is first to check to see if
+ * there is a handle, and then if not it goes on
+ * to call the init_lyr() routine.
+ *
+ * The non-obvious thing is that the ppm_init_lyr()
+ * routine, in addition to opening the device
+ * associated with the dc (domain control) in
+ * question, has the side-effect of creating the
+ * handle for that dc as well.
+ */
if (ppm_lookup_hndl(domp->model, dc) != NULL)
continue;
@@ -979,6 +1005,8 @@ struct ppm_confdefs {
char *sym;
int val;
} ppm_confdefs_table[] = {
+ "ENTER_S3", PPMDC_ENTER_S3,
+ "EXIT_S3", PPMDC_EXIT_S3,
"CPU_NEXT", PPMDC_CPU_NEXT,
"PRE_CHNG", PPMDC_PRE_CHNG,
"CPU_GO", PPMDC_CPU_GO,
@@ -991,7 +1019,9 @@ struct ppm_confdefs {
"LED_OFF", PPMDC_LED_OFF,
"KIO", PPMDC_KIO,
"VCORE", PPMDC_VCORE,
+#ifdef sun4u
"I2CKIO", PPMDC_I2CKIO,
+#endif
"CPUSPEEDKIO", PPMDC_CPUSPEEDKIO,
"PRE_PWR_OFF", PPMDC_PRE_PWR_OFF,
"PRE_PWR_ON", PPMDC_PRE_PWR_ON,
@@ -1103,14 +1133,20 @@ ppm_parse_dc(char **dc_namep, ppm_dc_t *dc)
(void) ppm_stoi(dclist[i], &dc->m_un.cpu.speeds);
continue;
}
+#ifdef sun4u
if (strstr(dclist[i], "mask=")) {
(void) ppm_stoi(dclist[i], &dc->m_un.i2c.mask);
continue;
}
+#endif
/* This must be before the if statement for delay */
if (strstr(dclist[i], "post_delay=")) {
+#ifdef sun4u
ASSERT(dc->method == PPMDC_KIO ||
dc->method == PPMDC_I2CKIO);
+#else
+ ASSERT(dc->method == PPMDC_KIO);
+#endif
/*
* all delays are uint_t type instead of clock_t.
* If the delay is too long, it might get truncated.
@@ -1119,13 +1155,15 @@ ppm_parse_dc(char **dc_namep, ppm_dc_t *dc)
switch (dc->method) {
case PPMDC_KIO:
(void) ppm_stoi(dclist[i],
- &dc->m_un.kio.post_delay);
+ &dc->m_un.kio.post_delay);
break;
+#ifdef sun4u
case PPMDC_I2CKIO:
(void) ppm_stoi(dclist[i],
- &dc->m_un.i2c.post_delay);
+ &dc->m_un.i2c.post_delay);
break;
+#endif
default:
break;
@@ -1133,9 +1171,14 @@ ppm_parse_dc(char **dc_namep, ppm_dc_t *dc)
continue;
}
if (strstr(dclist[i], "delay=")) {
+#ifdef sun4u
+ ASSERT(dc->method == PPMDC_VCORE ||
+ dc->method == PPMDC_KIO ||
+ dc->method == PPMDC_I2CKIO);
+#else
ASSERT(dc->method == PPMDC_VCORE ||
- dc->method == PPMDC_KIO ||
- dc->method == PPMDC_I2CKIO);
+ dc->method == PPMDC_KIO);
+#endif
/*
* all delays are uint_t type instead of clock_t.
@@ -1148,9 +1191,11 @@ ppm_parse_dc(char **dc_namep, ppm_dc_t *dc)
(void) ppm_stoi(dclist[i], &dc->m_un.kio.delay);
break;
+#ifdef sun4u
case PPMDC_I2CKIO:
(void) ppm_stoi(dclist[i], &dc->m_un.i2c.delay);
break;
+#endif
case PPMDC_VCORE:
(void) ppm_stoi(dclist[i], &dc->m_un.cpu.delay);
@@ -1227,6 +1272,8 @@ ppm_lookup_dc(ppm_domain_t *domp, int cmd)
case PPMDC_PWR_ON:
case PPMDC_RESET_OFF:
case PPMDC_RESET_ON:
+ case PPMDC_ENTER_S3:
+ case PPMDC_EXIT_S3:
break;
default:
PPMD(D_PPMDC, ("%s: cmd(%d) unrecognized\n", str, cmd))
@@ -1234,9 +1281,11 @@ ppm_lookup_dc(ppm_domain_t *domp, int cmd)
}
for (dc = domp->dc; dc; dc = dc->next) {
- if (dc->cmd == cmd)
+ if (dc->cmd == cmd) {
return (dc);
+ }
}
+
return (NULL);
}
@@ -1315,6 +1364,7 @@ ppm_get_ctlstr(int ctlop, uint_t mask)
FLINTSTR(D_LOCKS, PMR_PPM_UNLOCK_POWER),
FLINTSTR(D_LOCKS, PMR_PPM_TRY_LOCK_POWER),
FLINTSTR(D_LOCKS, PMR_PPM_POWER_LOCK_OWNER),
+ FLINTSTR(D_CTLOPS1 | D_CTLOPS2, PMR_PPM_ENTER_SX),
FLINTSTR(D_CTLOPS1 | D_CTLOPS2, PMR_UNKNOWN),
};
@@ -1334,13 +1384,15 @@ ppm_print_dc(ppm_dc_t *dc)
PPMD(D_PPMDC, ("\nAdds ppm_dc: path(%s),\n cmd(%x), "
"method(%x), ", d->path, d->cmd, d->method))
- if (d->method == PPMDC_I2CKIO) {
+ if (d->method == PPMDC_KIO) {
+ PPMD(D_PPMDC, ("kio.iowr(%x), kio.val(0x%X)",
+ d->m_un.kio.iowr, d->m_un.kio.val))
+#ifdef sun4u
+ } else if (d->method == PPMDC_I2CKIO) {
PPMD(D_PPMDC, ("i2c.iowr(%x), i2c.val(0x%X), "
"i2c.mask(0x%X)", d->m_un.i2c.iowr,
d->m_un.i2c.val, d->m_un.i2c.mask))
- } else if (d->method == PPMDC_KIO) {
- PPMD(D_PPMDC, ("kio.iowr(%x), kio.val(0x%X)",
- d->m_un.kio.iowr, d->m_un.kio.val))
+#endif
} else if (d->method == PPMDC_VCORE) {
PPMD(D_PPMDC, ("cpu: .iord(%x), .iowr(%x), .val(0x%X), "
".delay(0x%x)",