drivers/soc/fsl/rcpm.c

Source file repositories/reference/linux-study-clean/drivers/soc/fsl/rcpm.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/fsl/rcpm.c
Extension
.c
Size
4613 bytes
Lines
201
Domain
Driver Families
Bucket
drivers/soc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rcpm {
	unsigned int	wakeup_cells;
	void __iomem	*ippdexpcr_base;
	bool		little_endian;
};

#define  SCFG_SPARECR8	0x051c

static void copy_ippdexpcr1_setting(u32 val)
{
	struct device_node *np;
	void __iomem *regs;
	u32 reg_val;

	np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-scfg");
	if (!np)
		return;

	regs = of_iomap(np, 0);
	of_node_put(np);
	if (!regs)
		return;

	reg_val = ioread32be(regs + SCFG_SPARECR8);
	iowrite32be(val | reg_val, regs + SCFG_SPARECR8);

	iounmap(regs);
}

/**
 * rcpm_pm_prepare - performs device-level tasks associated with power
 * management, such as programming related to the wakeup source control.
 * @dev: Device to handle.
 *
 */
static int 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);

Annotation

Implementation Notes