drivers/soc/qcom/qcom-pbs.c

Source file repositories/reference/linux-study-clean/drivers/soc/qcom/qcom-pbs.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/qcom/qcom-pbs.c
Extension
.c
Size
5784 bytes
Lines
229
Domain
Driver Families
Bucket
drivers/soc
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 pbs_dev {
	struct device		*dev;
	struct regmap		*regmap;
	struct mutex		lock;
	struct device_link	*link;

	u32			base;
};

static int qcom_pbs_wait_for_ack(struct pbs_dev *pbs, u8 bit_pos)
{
	unsigned int val;
	int ret;

	ret = regmap_read_poll_timeout(pbs->regmap,  pbs->base + PBS_CLIENT_SCRATCH2,
				       val, val & BIT(bit_pos), DELAY, DELAY * RETRIES);

	if (ret < 0) {
		dev_err(pbs->dev, "Timeout for PBS ACK/NACK for bit %u\n", bit_pos);
		return -ETIMEDOUT;
	}

	if (val == PBS_CLIENT_SCRATCH2_ERROR) {
		ret = regmap_write(pbs->regmap, pbs->base + PBS_CLIENT_SCRATCH2, 0);
		dev_err(pbs->dev, "NACK from PBS for bit %u\n", bit_pos);
		return -EINVAL;
	}

	dev_dbg(pbs->dev, "PBS sequence for bit %u executed!\n", bit_pos);
	return 0;
}

/**
 * qcom_pbs_trigger_event() - Trigger the PBS RAM sequence
 * @pbs: Pointer to PBS device
 * @bitmap: bitmap
 *
 * This function is used to trigger the PBS RAM sequence to be
 * executed by the client driver.
 *
 * The PBS trigger sequence involves
 * 1. setting the PBS sequence bit in PBS_CLIENT_SCRATCH1
 * 2. Initiating the SW PBS trigger
 * 3. Checking the equivalent bit in PBS_CLIENT_SCRATCH2 for the
 *    completion of the sequence.
 * 4. If PBS_CLIENT_SCRATCH2 == 0xFF, the PBS sequence failed to execute
 *
 * Return: 0 on success, < 0 on failure
 */
int qcom_pbs_trigger_event(struct pbs_dev *pbs, u8 bitmap)
{
	unsigned int val;
	u16 bit_pos;
	int ret;

	if (WARN_ON(!bitmap))
		return -EINVAL;

	if (IS_ERR_OR_NULL(pbs))
		return -EINVAL;

	guard(mutex)(&pbs->lock);
	ret = regmap_read(pbs->regmap, pbs->base + PBS_CLIENT_SCRATCH2, &val);
	if (ret < 0)
		return ret;

	if (val == PBS_CLIENT_SCRATCH2_ERROR) {
		/* PBS error - clear SCRATCH2 register */
		ret = regmap_write(pbs->regmap, pbs->base + PBS_CLIENT_SCRATCH2, 0);
		if (ret < 0)
			return ret;
	}

	for (bit_pos = 0; bit_pos < 8; bit_pos++) {
		if (!(bitmap & BIT(bit_pos)))
			continue;

		/* Clear the PBS sequence bit position */
		ret = regmap_update_bits(pbs->regmap, pbs->base + PBS_CLIENT_SCRATCH2,
					 BIT(bit_pos), 0);
		if (ret < 0)
			break;

		/* Set the PBS sequence bit position */
		ret = regmap_update_bits(pbs->regmap, pbs->base + PBS_CLIENT_SCRATCH1,
					 BIT(bit_pos), BIT(bit_pos));
		if (ret < 0)
			break;

		/* Initiate the SW trigger */

Annotation

Implementation Notes