/** * scp_ipi_unregister() - unregister an ipi function * * @scp: mtk_scp structure * @id: IPI ID * * Unregister an ipi function to receive ipi interrupt from SCP.
*/ void scp_ipi_unregister(struct mtk_scp *scp, u32 id)
{ if (!scp) return;
/* * scp_memcpy_aligned() - Copy src to dst, where dst is in SCP SRAM region. * * @dst: Pointer to the destination buffer, should be in SCP SRAM region. * @src: Pointer to the source buffer. * @len: Length of the source buffer to be copied. * * Since AP access of SCP SRAM don't support byte write, this always write a * full word at a time, and may cause some extra bytes to be written at the * beginning & ending of dst.
*/ void scp_memcpy_aligned(void __iomem *dst, constvoid *src, unsignedint len)
{ void __iomem *ptr;
u32 val; unsignedint i = 0, remain;
__iowrite32_copy(dst + i, src + i, (len - i) / 4);
remain = (len - i) % 4;
if (remain > 0) {
val = readl_relaxed(dst + len - remain);
memcpy(&val, src + len - remain, remain);
writel_relaxed(val, dst + len - remain);
}
}
EXPORT_SYMBOL_GPL(scp_memcpy_aligned);
/** * scp_ipi_lock() - Lock before operations of an IPI ID * * @scp: mtk_scp structure * @id: IPI ID * * Note: This should not be used by drivers other than mtk_scp.
*/ void scp_ipi_lock(struct mtk_scp *scp, u32 id)
{ if (WARN_ON(id >= SCP_IPI_MAX)) return;
mutex_lock(&scp->ipi_desc[id].lock);
}
EXPORT_SYMBOL_GPL(scp_ipi_lock);
/** * scp_ipi_unlock() - Unlock after operations of an IPI ID * * @scp: mtk_scp structure * @id: IPI ID * * Note: This should not be used by drivers other than mtk_scp.
*/ void scp_ipi_unlock(struct mtk_scp *scp, u32 id)
{ if (WARN_ON(id >= SCP_IPI_MAX)) return;
mutex_unlock(&scp->ipi_desc[id].lock);
}
EXPORT_SYMBOL_GPL(scp_ipi_unlock);
/** * scp_ipi_send() - send data from AP to scp. * * @scp: mtk_scp structure * @id: IPI ID * @buf: the data buffer * @len: the data buffer length * @wait: number of msecs to wait for ack. 0 to skip waiting. * * This function is thread-safe. When this function returns, * SCP has received the data and starts the processing. * When the processing completes, IPI handler registered * by scp_ipi_register will be called in interrupt context. * * Return: 0 if sending data successfully, -error on error.
**/ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsignedint len, unsignedint wait)
{ struct mtk_share_obj __iomem *send_obj = scp->send_buf;
u32 val; int ret; conststruct mtk_scp_sizes_data *scp_sizes;
scp->ipi_id_ack[id] = false; /* send the command to SCP */
writel(scp->data->host_to_scp_int_bit,
scp->cluster->reg_base + scp->data->host_to_scp_reg);
if (wait) { /* wait for SCP's ACK */
ret = wait_event_timeout(scp->ack_wq,
scp->ipi_id_ack[id],
msecs_to_jiffies(wait));
scp->ipi_id_ack[id] = false; if (WARN(!ret, "scp ipi %d ack time out !", id))
ret = -EIO; else
ret = 0;
}
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.