drivers/devfreq/hisi_uncore_freq.c

Source file repositories/reference/linux-study-clean/drivers/devfreq/hisi_uncore_freq.c

File Facts

System
Linux kernel
Corpus path
drivers/devfreq/hisi_uncore_freq.c
Extension
.c
Size
16448 bytes
Lines
659
Domain
Driver Families
Bucket
drivers/devfreq
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 hisi_uncore_pcc_data {
	u16 status;
	u16 resv;
	u32 data;
};

struct hisi_uncore_pcc_shmem {
	struct acpi_pcct_shared_memory head;
	struct hisi_uncore_pcc_data pcc_data;
};

enum hisi_uncore_pcc_cmd_type {
	HUCF_PCC_CMD_GET_CAP = 0,
	HUCF_PCC_CMD_GET_FREQ,
	HUCF_PCC_CMD_SET_FREQ,
	HUCF_PCC_CMD_GET_MODE,
	HUCF_PCC_CMD_SET_MODE,
	HUCF_PCC_CMD_GET_PLAT_FREQ_NUM,
	HUCF_PCC_CMD_GET_PLAT_FREQ_BY_IDX,
	HUCF_PCC_CMD_MAX = 256
};

static int hisi_platform_gov_usage;
static DEFINE_MUTEX(hisi_platform_gov_usage_lock);

enum hisi_uncore_freq_mode {
	HUCF_MODE_PLATFORM = 0,
	HUCF_MODE_OS,
	HUCF_MODE_MAX
};

#define HUCF_CAP_PLATFORM_CTRL	BIT(0)

/**
 * struct hisi_uncore_freq - hisi uncore frequency scaling device data
 * @dev:		device of this frequency scaling driver
 * @cl:			mailbox client object
 * @pchan:		PCC mailbox channel
 * @chan_id:		PCC channel ID
 * @last_cmd_cmpl_time:	timestamp of the last completed PCC command
 * @pcc_lock:		PCC channel lock
 * @devfreq:		devfreq data of this hisi_uncore_freq device
 * @related_cpus:	CPUs whose performance is majorly affected by this
 *			uncore frequency domain
 * @cap:		capability flag
 */
struct hisi_uncore_freq {
	struct device *dev;
	struct mbox_client cl;
	struct pcc_mbox_chan *pchan;
	int chan_id;
	ktime_t last_cmd_cmpl_time;
	struct mutex pcc_lock;
	struct devfreq *devfreq;
	struct cpumask related_cpus;
	u32 cap;
};

/* PCC channel timeout = PCC nominal latency * NUM */
#define HUCF_PCC_POLL_TIMEOUT_NUM	1000
#define HUCF_PCC_POLL_INTERVAL_US	5

/* Default polling interval in ms for devfreq governors*/
#define HUCF_DEFAULT_POLLING_MS 100

static void hisi_uncore_free_pcc_chan(struct hisi_uncore_freq *uncore)
{
	guard(mutex)(&uncore->pcc_lock);
	pcc_mbox_free_channel(uncore->pchan);
	uncore->pchan = NULL;
}

static void devm_hisi_uncore_free_pcc_chan(void *data)
{
	hisi_uncore_free_pcc_chan(data);
}

static int hisi_uncore_request_pcc_chan(struct hisi_uncore_freq *uncore)
{
	struct device *dev = uncore->dev;
	struct pcc_mbox_chan *pcc_chan;

	uncore->cl = (struct mbox_client) {
		.dev = dev,
		.tx_block = false,
		.knows_txdone = true,
	};

	pcc_chan = pcc_mbox_request_channel(&uncore->cl, uncore->chan_id);
	if (IS_ERR(pcc_chan))

Annotation

Implementation Notes