drivers/firmware/samsung/exynos-acpm-dvfs.c

Source file repositories/reference/linux-study-clean/drivers/firmware/samsung/exynos-acpm-dvfs.c

File Facts

System
Linux kernel
Corpus path
drivers/firmware/samsung/exynos-acpm-dvfs.c
Extension
.c
Size
1763 bytes
Lines
69
Domain
Driver Families
Bucket
drivers/firmware
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

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2020 Samsung Electronics Co., Ltd.
 * Copyright 2020 Google LLC.
 * Copyright 2025 Linaro Ltd.
 */

#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/firmware/samsung/exynos-acpm-protocol.h>
#include <linux/ktime.h>
#include <linux/types.h>
#include <linux/units.h>

#include "exynos-acpm.h"
#include "exynos-acpm-dvfs.h"

#define ACPM_DVFS_ID			GENMASK(11, 0)
#define ACPM_DVFS_REQ_TYPE		GENMASK(15, 0)

#define ACPM_DVFS_FREQ_REQ		0
#define ACPM_DVFS_FREQ_GET		1

static void acpm_dvfs_init_set_rate_cmd(u32 cmd[4], unsigned int clk_id,
					unsigned long rate)
{
	cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id);
	cmd[1] = rate / HZ_PER_KHZ;
	cmd[2] = FIELD_PREP(ACPM_DVFS_REQ_TYPE, ACPM_DVFS_FREQ_REQ);
	cmd[3] = ktime_to_ms(ktime_get());
}

int acpm_dvfs_set_rate(struct acpm_handle *handle,
		       unsigned int acpm_chan_id, unsigned int clk_id,
		       unsigned long rate)
{
	struct acpm_xfer xfer = {0};
	u32 cmd[4];

	acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate);
	acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, false);

	return acpm_do_xfer(handle, &xfer);
}

static void acpm_dvfs_init_get_rate_cmd(u32 cmd[4], unsigned int clk_id)
{
	cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id);
	cmd[2] = FIELD_PREP(ACPM_DVFS_REQ_TYPE, ACPM_DVFS_FREQ_GET);
	cmd[3] = ktime_to_ms(ktime_get());
}

unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle,
				 unsigned int acpm_chan_id, unsigned int clk_id)
{
	struct acpm_xfer xfer;
	unsigned int cmd[4] = {0};
	int ret;

	acpm_dvfs_init_get_rate_cmd(cmd, clk_id);
	acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);

	ret = acpm_do_xfer(handle, &xfer);
	if (ret)
		return 0;

	return xfer.rxd[1] * HZ_PER_KHZ;
}

Annotation

Implementation Notes