/** * rcpm_pm_prepare - performs device-level tasks associated with power * management, such as programming related to the wakeup source control. * @dev: Device to handle. *
*/ staticint rcpm_pm_prepare(struct device *dev)
{ int i, ret, idx; void __iomem *base; struct wakeup_source *ws; struct rcpm *rcpm; struct device_node *np = dev->of_node;
u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1];
u32 setting[RCPM_WAKEUP_CELL_MAX_SIZE] = {0};
rcpm = dev_get_drvdata(dev); if (!rcpm) return -EINVAL;
base = rcpm->ippdexpcr_base;
idx = wakeup_sources_read_lock();
/* Begin with first registered wakeup source */
for_each_wakeup_source(ws) {
/* skip object which is not attached to device */ if (!ws->dev || !ws->dev->parent) continue;
ret = device_property_read_u32_array(ws->dev->parent, "fsl,rcpm-wakeup", value,
rcpm->wakeup_cells + 1);
if (ret) continue;
/* * For DT mode, would handle devices with "fsl,rcpm-wakeup" * pointing to the current RCPM node. * * For ACPI mode, currently we assume there is only one * RCPM controller existing.
*/ if (is_of_node(dev->fwnode)) if (np->phandle != value[0]) continue;
/* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines the * number of IPPDEXPCR register cells, and "fsl,rcpm-wakeup" * of wakeup source IP contains an integer array: <phandle to * RCPM node, IPPDEXPCR0 setting, IPPDEXPCR1 setting, * IPPDEXPCR2 setting, etc>. * * So we will go thought them to collect setting data.
*/ for (i = 0; i < rcpm->wakeup_cells; i++)
setting[i] |= value[i + 1];
}
wakeup_sources_read_unlock(idx);
/* Program all IPPDEXPCRn once */ for (i = 0; i < rcpm->wakeup_cells; i++) {
u32 tmp = setting[i]; void __iomem *address = base + i * 4;
if (!tmp) continue;
/* We can only OR related bits */ if (rcpm->little_endian) {
tmp |= ioread32(address);
iowrite32(tmp, address);
} else {
tmp |= ioread32be(address);
iowrite32be(tmp, address);
} /* * Workaround of errata A-008646 on SoC LS1021A: * There is a bug of register ippdexpcr1. * Reading configuration register RCPM_IPPDEXPCR1 * always return zero. So save ippdexpcr1's value * to register SCFG_SPARECR8.And the value of * ippdexpcr1 will be read from SCFG_SPARECR8.
*/ if (dev_of_node(dev) && (i == 1)) if (of_device_is_compatible(np, "fsl,ls1021a-rcpm"))
copy_ippdexpcr1_setting(tmp);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.