drivers/reset/reset-mpfs.c

Source file repositories/reference/linux-study-clean/drivers/reset/reset-mpfs.c

File Facts

System
Linux kernel
Corpus path
drivers/reset/reset-mpfs.c
Extension
.c
Size
5283 bytes
Lines
208
Domain
Driver Families
Bucket
drivers/reset
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 mpfs_reset {
	struct regmap *regmap;
	struct reset_controller_dev rcdev;
};

static inline struct mpfs_reset *to_mpfs_reset(struct reset_controller_dev *rcdev)
{
	return container_of(rcdev, struct mpfs_reset, rcdev);
}

/*
 * Peripheral clock resets
 */
static int mpfs_assert(struct reset_controller_dev *rcdev, unsigned long id)
{
	struct mpfs_reset *rst = to_mpfs_reset(rcdev);

	return regmap_set_bits(rst->regmap, REG_SUBBLK_RESET_CR, BIT(id));

}

static int mpfs_deassert(struct reset_controller_dev *rcdev, unsigned long id)
{
	struct mpfs_reset *rst = to_mpfs_reset(rcdev);

	return regmap_clear_bits(rst->regmap, REG_SUBBLK_RESET_CR, BIT(id));

}

static int mpfs_status(struct reset_controller_dev *rcdev, unsigned long id)
{
	struct mpfs_reset *rst = to_mpfs_reset(rcdev);
	u32 reg;

	regmap_read(rst->regmap, REG_SUBBLK_RESET_CR, &reg);

	/*
	 * It is safe to return here as MPFS_NUM_RESETS makes sure the sign bit
	 * is never hit.
	 */
	return (reg & BIT(id));
}

static int mpfs_reset(struct reset_controller_dev *rcdev, unsigned long id)
{
	mpfs_assert(rcdev, id);

	usleep_range(MPFS_SLEEP_MIN_US, MPFS_SLEEP_MAX_US);

	mpfs_deassert(rcdev, id);

	return 0;
}

static const struct reset_control_ops mpfs_reset_ops = {
	.reset = mpfs_reset,
	.assert = mpfs_assert,
	.deassert = mpfs_deassert,
	.status = mpfs_status,
};

static int mpfs_reset_xlate(struct reset_controller_dev *rcdev,
			    const struct of_phandle_args *reset_spec)
{
	unsigned int index = reset_spec->args[0];

	/*
	 * CLK_RESERVED does not map to a clock, but it does map to a reset,
	 * so it has to be accounted for here. It is the reset for the fabric,
	 * so if this reset gets called - do not reset it.
	 */
	if (index == CLK_RESERVED) {
		dev_err(rcdev->dev, "Resetting the fabric is not supported\n");
		return -EINVAL;
	}

	if (index < MPFS_PERIPH_OFFSET || index >= (MPFS_PERIPH_OFFSET + rcdev->nr_resets)) {
		dev_err(rcdev->dev, "Invalid reset index %u\n", index);
		return -EINVAL;
	}

	return index - MPFS_PERIPH_OFFSET;
}

static int mpfs_reset_mfd_probe(struct platform_device *pdev)
{
	struct reset_controller_dev *rcdev;
	struct device *dev = &pdev->dev;
	struct mpfs_reset *rst;

Annotation

Implementation Notes