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)
{ unsignedint 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 */
ret = regmap_update_bits(pbs->regmap, pbs->base + PBS_CLIENT_TRIG_CTL,
PBS_CLIENT_SW_TRIG_BIT, PBS_CLIENT_SW_TRIG_BIT); if (ret < 0) break;
ret = qcom_pbs_wait_for_ack(pbs, bit_pos); if (ret < 0) break;
/* Clear the PBS sequence bit position */
regmap_update_bits(pbs->regmap, pbs->base + PBS_CLIENT_SCRATCH1, BIT(bit_pos), 0);
regmap_update_bits(pbs->regmap, pbs->base + PBS_CLIENT_SCRATCH2, BIT(bit_pos), 0);
}
/* Clear all the requested bitmap */ return regmap_update_bits(pbs->regmap, pbs->base + PBS_CLIENT_SCRATCH1, bitmap, 0);
}
EXPORT_SYMBOL_GPL(qcom_pbs_trigger_event);
/** * get_pbs_client_device() - Get the PBS device used by client * @dev: Client device * * This function is used to get the PBS device that is being * used by the client. * * Return: pbs_dev on success, ERR_PTR on failure
*/ struct pbs_dev *get_pbs_client_device(struct device *dev)
{ struct platform_device *pdev; struct pbs_dev *pbs;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.